zoukankan      html  css  js  c++  java
  • 第九章 竞品技术分析

    开机速度

    1. splash广告逻辑,首次加载的图片为应用放在res文件夹下面几个文件夹里面的图片,同时会去调用接口获取下一次打开的时候要显示的图片url,并缓存图片;下次进入该界面显示图片并继续访问接下来一次的图片,为了保证打开速度,这个网络请求务必异步处理。
    2. 引导图,不要超过4页。动画可原生实现,可gif,可视频来实现。
    3. 进入首页之前进行地理位置的定位,保证进入首页显示的数据为当前城市的信息。
    4. app首页设计,尽可能多的将所有产品展示在首页,会有广告,搜索栏,滚动条。

      上面为用户可见的数据,一些不可见数据:

    1. umeng打点,统计激活数。
    2. 注册推送。
    3. 根据推送协议进行页面跳转。
    4. 初始化崩溃收集机制,比如崩溃信息上传等。

    为了加快splash的加载速度建议客户端这边尽可能避免耗时间的任务操作

    html5页面打开速度

    1. 将html5数据打包进zip包里面去,每次从本地zip解压文件里面加载html5数据;新增或者修改html5信息怎么办,进行版本控制,如果版本一致,加载本地解压数据,如果不是加载新的zip包的解压数据;其中公共的,不变化的html5数据压缩为公用的zip压缩包并下发,那么每次下载的时候只下载新增和修改的那部分html5文件的压缩包。在上个页面设置不可显示的webview加载html5数据,在下个webview加载的时候直接从本地缓存文件里面去加载。

    安装包大小

    1. app安装包一定要小,或者实现增量更新,减少对用户流量的不必要耗费。 
    2. 图片,音频,视频文件应该在前期提供的时候就尽可能处理的体积足够小。

           我的观点:

      对于分享,推送,定位,地图等第三方服务集成的时候,能用微信官方,新浪官方自己去实现就尽可能自己去实现,因为团队里面有人为了实现分享集成umeng分享功能,导致应用大小增加4M知道,其中包括很多无用的代码和资源文件,请慎重。

    png和jpg的使用场景

    1. 同背景图片,png加载速度大于jpg,手机会对png进行硬件加速。
    2. 网络图片采用jpg图片比较合适。
    3. 广告图,引导图采用jpg比较合适。

    splash图片,引导图,背景图

    1. splash图片现在在300-500k之间。
    2. 引导图可以将背景图片和前景图片分开,实现背景图片或者前景图片的可重用性。
    3. 背景图限制在1M以内,并没必要png格式,jpg格式就行了。

    表情包的方案同上面html5页面打开速度的论述,都是通过zip来进行增量更新。

    清理无用代码和资源文件

    1. eclipse时代用undector可以实现无用代码的检测,android studio暂时没发现,无用资源文件可以通过link来实现无用资源文件,无用style等检测,但是还是需要手动进行删除。
    2. 通过使用proguard来配置混淆代码文件来清理无用的代码,减少apk的大小。

    性能优化

    1. 网络请求优化:针对2G,3G,4G,wifi环境服务器端配置不同的服务器,分别接入移动,联通,电信的专线,并在客户端进行配置,app登录获取遍历访问2G,3G,4G,wifi的针对性域名并判断出最佳的访问素的的域名,并在一段时间内访问该域名。为了避免抢占同一服务器的资源,可以在服务器端设置针对的优先级。
    2. 抛弃使用http+json,转而使用tcp+protobuf。

    页面跳转逻辑解耦

     我个人项目里面是写个路由类,所有的跳转逻辑都写在这个路由类里面,作为所有activity界面跳转中间控制层。

    作者利用反射也提供了一个不错的思路:

    import android.app.Activity;
    import android.content.Intent;
    
    public abstract class BaseActivity extends Activity {
    
        public void navigateTo(final String activityName, 
                final Intent intent) {
            
            //在这个位置执行页面打点的操作,这里可以利用到activityName
            
            Class<?> clazz = null;
            try {
                clazz = Class.forName(activityName);
                if (clazz != null) {
                    intent.setClass(this, clazz);
                    this.startActivity(intent);
                }
            } catch (final ClassNotFoundException e) {
                return;
            }
        }
    }

    activity的常量类:

    public class ActivityNameConstants {
        public final static String SecondActivity 
            = "com.example.navigator.SecondActivity";
    }

    demo:

    import android.content.Intent;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends BaseActivity {
    
        Button btnNav1, btnNav2;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            btnNav1 = (Button) findViewById(R.id.btnNav1);
            btnNav1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(MainActivity.this,
                            SecondActivity.class);
                    startActivity(intent);
                }
            });
    
            btnNav2 = (Button) findViewById(R.id.btnNav2);
            btnNav2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.putExtra("name", "Jianqiang");
                    navigateTo(ActivityNameConstants.SecondActivity, intent);
                }
            });
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }
    
    }

    个人认为各有优缺点,还是看自己的偏好吧。

    打点统计

    页面打点:放在跳转逻辑代码前面;

    事件打点:打点逻辑写在基类控件里面,比如写onclick等触发事件的基类,并在这些基类里面写事件打点的逻辑。

     多渠道打包

     我一般是上传到360,百度等加固平台惊醒加固打包,然后利用平台的多渠道打包工具进行批量多渠道打包,书里面讲的是python程序来实现,你可以去github找找,这类代码很多。

    class.dex的拆与合

    主要还是处理65536的问题,2种方案:

    1. 插件化:独立模块做成单独的apk,使用dexClassLoader来进行加载。
    2. dex分包:主要利用multidex来实现class.dex的拆分。

    模块化拆分

    android代码的模块化拆分:

    1. 将常用的工具类代码,封装代码,第三方代码单独封装为基础类库。
    2. 指定资源文件命名规范,并以模块名称作为前缀来进行命名。
    3. 模块间传递的数据以json或者单独拉出来公用的bean作为一个库引用。

    版本策略:

    一般情况下版本名称为3位:比如6.0.0

    第一位为大版本更新,第二位用于小版本迭代,第三位作为紧急发版。

  • 相关阅读:
    csp-s测试41 T2 影子
    模拟测试15 T3:rps (概率期望, 神*DP)
    考试沙币错误
    测试40
    水管局长 Lct
    测试32:chemistry
    测试35:抽卡
    模拟30,树
    考试策略&&模拟30经验总结:
    模拟测试28
  • 原文地址:https://www.cnblogs.com/androidsuperman/p/5599312.html
Copyright © 2011-2022 走看看