保活 先从老式最基础的开始:

  • 使用startService方式启动一个独立进程的服务,这样系统会在service意外死亡后自动重启。
  • 使用RTC定时闹钟每5分钟检测一下(4.0以上基本无效)
  • 启动linux守护进程,每几分钟检测一下进程是否存在,不存在就startService(5.0以下除MIUI和华为外有效)
  • 5.0以上使用JobScheduler代替闹钟定时检测启动 。
  • 启动隐藏的前台通知。(支付宝即采用该方式,为系统的一个bug,在7.1.1中已修复,具体体现为下拉任务栏可以看到该通知。)但这些措施都不能100%保活。尤其是M中引入的doze模式,在doze模式中甚至无网络连接。
  • 官方建议:1.引导用户加入白名单;2.使用Google系列服务如GCM,Firebase

内存三级缓存思路 对于列表页中的图片应使用LRU之类的内存缓存,对于activity和fragment销毁时应该把其对应的图片释放掉。每个图片都是有依赖引用的,我们一般默认是fragment或者是activity,当activity或者fragment销毁时,我们会将只依赖当前页面的图片移出LRU进行释放。

  • 内存图片缓存还是有三级:一级是bitmap列表,一级是LRU强引用,一级是弱引用。加载图片时,先在弱引用缓存和LRU强引用中查找没有被释放的bitmap,如果存在并满足复用条件,则不创建bitmap,而使用该图片内存,之后将其从弱引用或者LRU中移出放入bitmap列表强引用中。bitmap列表强引用保存了该图片依赖的直接控件。当view的onDetachedFromWindow被调用则从bitmap列表中移除只有依赖该view的对象到LRU强应用中。如果LRU强引用满了则放到弱引用中。
  • 这种方案可以达到如下效果:列表滑动、或者打开新页面时会申请较小的内存或不申请内存。列表页来回滑动时依然有缓存可用。
  • 对于adapterView和recycleView中的控件则需单独写个工具方法来封装一下。
  • 这里实际上已经不需要弱引用了,只要从LRU中移除即可调用recycle方法释放该图片。
  • 图片内存的申请和释放都由框架来控制,不由gc管理。
  • LRU的大小就是可调,它里面的图片内存是都可以释放的,它只是作为缓存而存在。

卡顿问题快速定位的方法GPU monitor分析

  • 打开开发者模式中GPU呈现模式分析,查看是那种颜色条高
  • 如果是蓝色偏高,说明是单位消息里CPU太耗时,得把方法的执行都打出来看看哪个耗时。比如,在某处先看看是不是应该出现onMeasure,然后可以通过sdk自带的View布局工具,看一下哪个View的onMeasure耗时最多。
  • 如果红色偏高,说明GPU忙不过来。优化过渡绘制,使用离屏缓存来优化。
  • 黄色偏高,说明半透明GPU不仅在忙着绘制你的window也还忙着绘制别的,可能的情况为透明window叠加多了,window里的contentView有多个且相对复杂,或者GPU降频了等等,想具体分析需要查看GPU的trace。
  • 画动画时蓝色偏高是不正常的

**蓝色偏高的常见原因:**1. 动画或者交互时缓存失效的太多,验证方法是打出方法trace看看是不是有很多次的invalidate调用和dispatchDraw耗时在前面。2. 触发了GC,验证看看trace中主线程是不是被莫名的暂停了。3. 触发了layout,这种蓝色会很高,trace中measure方法会耗时较高。

如何优化启动速度 没有闪屏页activity,一旦存在闪屏页activity那么启动速度就不大可能在200ms内跳过。 把window的背景设置为闪屏页,一旦MainActivity加载完毕就显示主页了。 虽然用户也会看到一个类似的闪屏页,但那个闪屏页实际只是activity在theme中设置的background。 之前好像有人问我怎么优化启动速度。这个方案适合启动画面不是作为广告页只是过渡页使用的场景。

<item name="android:windowBackground">@drawable/splash_logo</item>
复制代码

自定义高性能可拖动GridView 在拖动过程中没有触发过invalidate,也没有触发requestLayout,别的应用每次移动动画会触发notifyDateChange,这会触发layout,影响性能。我们在拖动过程中会建立虚拟的视觉关系,只要不松手就会改变子view的顺序,只有松手才触发datechange。 提升性能绘制方法

  • 调用方法把它移出可见区域,移出可见区域后,在进行绘制的时候 native 层也不会去绘制它。

TextView优化

  • 列表直接不用textview,自定义view,通过提前缓存 StaticLayout提升TextView性能,可参考:http://ragnraok.github.io/textview-pre-render-research.html

Fragment留意点 每个页面都是Fragment,自己管理其生命周期和栈,每次启动是以window的方式添加进来,进入动画为window动画,手势回退为View动画,为了节省内存,页面栈只保留2个对象,FragmentManager会进行回收释放和Fragment的恢复。

  • 优点:加载动画非常流畅,内存占用低,支持页面的无穷层级叠加。
  • 缺点:以Window方式启动,很多系统的特性需要自己实现,难以驾驭。

状态栏兼容注意点 针对状态栏我们单独适配了4.4以上版本,5.0以上版本,6.0以上版本,Flyme系统,6.0以上的Flyme系统,MIUI系统,6.0以上的MIUI系统,YunOS系统,VIVO Funtouch 2.5以下版本和2.5以上版本.......

try-catch

  • 如果你的代码一定会抛出异常,那try catch会有一些影响。
  • 一旦捕获到异常,系统打到寄存器中获取当前函数调用栈,生成一堆信息,这总归是浪费性能的。
  • 所以说一般不影响,非要扣那肯定影响,本来get方法可以进行内联的,用来try catch肯定就不能进行内联优化了,就会让性能下降一点。
  • android这几个版本推出了JIT,art虚拟机中重点对内联函数的范围进行扩充,try catch会阻止这些优化。
  • 在android 5.0以上(ART进行OPT优化时)所有函数中存在try catch的方法都不能被JIT优化和进行内联优化

查看应用真实内存

  • adb shell dumpsys meminfo 你的包名 (monitor中不会显示WebView的内存占用)

  • (注意点)开了线程来执行耗时操作,可是这耗时操作执行的时候把主线的CPU占用给抢了。。。。

高绘制性能函数 看一个ListView的函数

offsetChildrenTopAndBottom(int index)
复制代码

这个方法性能很高,但是隐藏方法,listView移动子控件是用这个方法来移动的,它不破坏缓存,系统相当于是做了1+1+1+2,我们自己做就是1+2+1+2+1+2,我们自己写ListView的时候发现了这个函数,我们做for循环的性能还是不如系统的这个隐藏方法。

使用windowManager的addView来添加控件 例子:通过调用Fragment的onCreateView来生成一个View,然后addView进来,这导致跳转界面需要较长时间。现在得先addView一个View到windowManager中,然后在调用onCreateView,因为windowManager添加控件是在server进程,所以会立即addView进来,这时这里的View就需要显示点东西,这就需要类似windowBackground的东西来显示。windowBackground它存在的目的就是为了加快界面响应。

实现自己的windowbackground 先add一个类似decoreView进来,设置decoreView的background为windowBackground,然后在往这个decoreView上添加实际的控件。

避免使用LayoutParams实现动画

  • setLayoutParams()会触发requestLayout()从而导致所有View重新measure、layout、draw,导致卡顿。 排查方法:可以用布局边界排查大小变化的。 例:爱范儿 下拉刷新。(排查方法为:重写顶端控件的requestLayout方法,打上断点,看看动画或者交互过程中谁调用到了这个方法)

  • 还有查看谁刷新了页面导致重绘的排查方法是:重写顶端控件的invalidateChildInParent方法,看看谁调用到了。

使用硬件离屏缓存进行优化。(要保证缓存不失效)

正确的使用:显示硬件层更新绿色闪一下。错误的使用:过程中一直绿色。错误例:微信大图。正确例:掌阅首页切换
复制代码
  • 硬件加速本质上是属于window级别的东西,在创建ViewRootImpl的时候就确定了是否使用硬件加速,View级别所谓的关闭只是创建一张bitmap然后调用View的draw方法往这个上面绘制,绘制完成再往硬件加速的canvas上绘制。
  • 系统对OpenGl方法进行了封装和优化,封装实现了canvas的方法,使用它有的时候比直接使用OpenGl性能还好。所以开硬件加速几乎等效于调用OpenGl接口来绘制,OpenGl是通用绘制接口,一般GPU都会实现这些接口,所以硬件加速是让GPU来绘制,而非硬件加速就是CPU自己绘制。
  • CPU要实现那么多的通用计算,而GPU就那么几个简单接口,它就极端优化,所以这几个简单方法的性能非常高。(OpenGl标准方法创建纹理很耗时,一张1080p的全屏图需要40ms以上,而android系统自己私有的方法10ms以内就创建完毕了)
  • Opengl创建纹理(texture)太耗时,后面使用比系统的速度快,系统被它那套递归绘制等拖累了性能。(opengl来实现ViewPager的效果,android2.2手机除了初始化创建交互的纹理,进行移动的时候8ms左右一帧。)

主动释放控件资源

    //释放布局资源private void releaseDradable(View view){if (view instanceof ViewGroup) {int count = ((ViewGroup)view).getChildCount();for (int i=0;i<count;i++) {View childView = ((ViewGroup)view).getChildAt(i);if (childView instanceof ViewGroup) {releaseDradable(childView);}else {releaseOneDrawable(childView);}}}else {releaseOneDrawable(view);}}
//释放常见控件的资源,imageView是多种控件的根类
private void releaseOneDrawable(View view){if (view !=null) {BitmapDrawable src;BitmapDrawable backGround;if (view instanceof ImageView) {src = (BitmapDrawable) ((ImageView) view).getDrawable();recycleBitmap(src.getBitmap());}backGround = (BitmapDrawable) view.getBackground();recycleBitmap(backGround.getBitmap());}
}
private  void recycleBitmap(Bitmap bitmap) {if (bitmap != null && !bitmap.isRecycled()) {bitmap.recycle();bitmap = null;    }
}
复制代码

以上思路存在一个问题,即当某一个资源被多个activity引用时,回收该资源则会造成其他持有该资源的activity发生异常。

  • 维护一个Drawable链表用以记录引用次数

  • 将控件的getDrawable()和getBackground()设置为null

系统Viewpager的性能优化

  • V4包里的SwipeRefreshLayout类在接收到down事件的时候,会调用bringToFront方法,该方法会触发requestLayout。

*这里主要是优化ViewPager在添加和删除item的时候,会触发requestLayout导致的卡顿问题。第一次加载是没有优化的,因为必须得触发layout。 * 经过分析,我们的场景不需要这个方法,就去掉了该方法, viewPager的adapter中instantiateItem()会执行container.addView(object),这也会触发requestLayout;destroyItem也会触发requestLayout。可以替换为attachViewToParent和detachViewFromParent方法来进行add和remove。这俩方法是listView中进行动态add和remove的方法,性能很高,不会让缓存失效和触发requestLayout。

我们的ViewPager的setOffscreenPageLimit设置为1。调用detachViewFromParent方法后为了让ViewPager重新录制一下View的绘制,所以又手动调用了invalidate。 录制绘制就是dispatchDraw流程,不然会走getDisplayList流程

在 instantateItem()中调用如下代码

微信db打开方式 用户设备的IMEI+uin值计算MD5值,注意是小写字符,然后在取MD5的前7位字符构成的密码。

关于RelativeLayout的使用 大量使用了RelativeLayout,导致了多次mesure,一个relativelayout都要measure两次,多个层次这种叠加之后,measure次数指数级上升。

关于 SoftwareRefrence 在android低版本上,SoftwareRefrence是遵循java标准的GC回收流程,即只有触发GC的情况为内存不足时,才会去检查SoftReference,但在高版本上,SoftReference被检查的更频繁了,即不是只有内存不足时才去检查,其存在的概率与WeakReference接近。

FragmentTabHost的问题 每次FragmentTabHost切换fragment时会调用onCreateView()重绘UI。 解决方法:

   private FragmentTransaction doTabChanged(String tabId,FragmentTransaction ft) {TabInfo newTab = null;for (int i = 0; i < mTabs.size(); i++) {TabInfo tab = mTabs.get(i);if (tab.tag.equals(tabId)) {newTab = tab;}}if (newTab == null) {throw new IllegalStateException("No tab known for tag " + tabId);}if (mLastTab != newTab) {if (ft == null) {ft = mFragmentManager.beginTransaction();}if (mLastTab != null) {if (mLastTab.fragment != null) {// 将detach替换为hide,隐藏Fragment// ft.detach(mLastTab.fragment);ft.hide(mLastTab.fragment);}}if (newTab != null) {if (newTab.fragment == null) {newTab.fragment = Fragment.instantiate(mContext,newTab.clss.getName(), newTab.args);ft.add(mContainerId, newTab.fragment, newTab.tag);} else {// 将attach替换为show,显示Fragment// ft.attach(newTab.fragment);ft.show(newTab.fragment);}}mLastTab = newTab;}return ft;}
复制代码

app启动优化

  • 之前优化软件启动时间的时候,就是Application的attachBaseContext()开启method trace,首页的dispatchDraw方法被调用之后关闭,然后这段时间CPU都干了什么。

  • 耗时的操作放到了dispatchDraw方法之后post一个回调来执行。

    Looper.getMainLooper().setMessageLogging(new Printer() {@Overridepublic void println(String x) {Log.e("msg", x);}});
    复制代码

用这个来测算每个消息花了多长时间,如果消息的执行时间超过了16ms,则获取当前的函数调用栈。 (可以确保你的耗时操作在页面显示之后才执行。)

  • 或者还有个onPostResume()方法,我们现在已经不用View的绘制之后再执行操作了,我们改为放到onPostResume方法中执行。(draw方法执行了,页面就显示了,然后不会黑屏或者白屏了)
  • app启动流程:Application的构造方法->attachBaseContext()->onCreate()->Activity的构造方法->onCreate()->配置主题中背景灯属性->onStart()...

关于inflate

  • inflate本身是io操作,而手机性能下降很大的一个原因就是io性能变差。

  • 动态添加可以解决 xml 加载时间问题;自定义view 可以解决嵌套层级问题。

strings文件下多个同种类型字符串的问题

  • 共有%1s单
  • ]]>

RecyclerView的item的其他思路

  • recyleView中所有类型的item均为继承View,内容完全自己canvas绘制(一个个add进去),View中保存每个item的状态,获得该状态则可绘制出该View,bindView中无xml的inflate,已展示过的item再次显示时无需measure和耗时计算,ViewPager中limited item数为默认1,item被移除时,View内存被释放,再次进入时依靠保存的数据复原原item,此为同步操作。目前看来复原速度很快,用户对其是复原还是缓存的是感知不出来的。
  • android的新版本上也measure的结果进行了缓存,文本的测量也使用了100多K的空间进行全局缓存。

今日头条跟手回退实现--群分享记录

  • 今日头条也是基于Activity的透明主题来实现的,但是这个方案都有两个缺点,一就是叠加层级一多,滑动性能会下降明显,基本叠加5层就很卡了,二是透明主题破坏了系统内存回收释放的策略,导致所有的activity都是前台Activity,系统都不会回收,就会OOM。解决这个问题有一个方案就是利用android 4.4里提供的动态设置Activity透明主题来实现,当叠加了三层之后就将底部的第三层改为非透明主题。

           /*** 动态将一个activity设置为不透明主题** @param activity*/public static void convertActivityFromTranslucent(Activity activity) {try {Method method = Activity.class.getDeclaredMethod("convertFromTranslucent");method.setAccessible(true);method.invoke(activity);} catch (Throwable t) {}}
    复制代码
         /*** 动态将一个activity设置为透明主题** @param activity*/public static void convertActivityToTranslucent(Activity activity) {try {Class<?>[] classes = Activity.class.getDeclaredClasses();Class<?> translucentConversionListenerClazz = null;for (Class clazz : classes) {if (clazz.getSimpleName().contains("TranslucentConversionListener")) {translucentConversionListenerClazz = clazz;}}if (Build.VERSION.SDK_INT < 21) {//这个也仅支持4.4及以上Method method = Activity.class.getDeclaredMethod("convertToTranslucent",translucentConversionListenerClazz);method.setAccessible(true);method.invoke(activity, new Object[]{null});} else {//5.0以上的系统Method method = Activity.class.getDeclaredMethod("convertToTranslucent",translucentConversionListenerClazz,ActivityOptions.class);method.setAccessible(true);method.invoke(activity, null, null);}} catch (Throwable t) {t.printStackTrace();}}复制代码
  • 反编译了QQ空间的apk,他们把每个类的构造函数中添加了一行Zygote.class.getName(),Zygote是系统中存在的一个类。他们选用Zygote是android SDK中不存在的,被隐藏的类,他们应该是认为以后每个版本系统中都会有这个类,所以才选择了它。那么系统进行检查的时候就不会认为初始化该类只需要使用当前Dex。(防止CLASS_ISPREVERIFIED )

  • animation有个onAnimationStart和onAnmationEnd方法里面不可使用addView/removeView的方法,有可用handler.postRunable()来执行;开启硬件加速的时候有一些手机上会有概率性问题。硬件加速中draw流程只是进行录制,如果在录制的之后进行绘制的时候发现之前录制的已经无效了,在4.X的机型上就可能发生崩溃。动画的回调是在draw流程中执行的,在回调进行动态的removeView就会导致录制的绘制命令无效。

  • 线程的使用

ArrayList <File> list = new ArrayList<>();public void scanDir(String dirString){File dirFile = new File(dirString);list.add(dirFile);while (list.size() > 0){File files[] = list.remove(0).listFiles();for(File file : files){if(file.isDirectory()){list.add(file);}else{if(file.getAbsolutePath().endsWith("mp3")){Log.e("", "这是音乐文件");}}}}}
复制代码

把递归变成队列,再把队列变成多线程执行,下面只需要开启多个线程来执行scanDir(),比如一共有n+1(CPU核心数+1)个线程来执行scanDir(),当list有第一个元素时开启一个线程执行scanDir(),这个线程会往list中继续添加元素,当开启的线程小于n+1时,继续开启线程,直到达到n+1,达到之后就等待线程执行完毕,其中某个线程执行完毕之后再次去list中获取底部的元素来执行scanDir,直到list大小为0。

  • LayoutParams 的问题 直接new出来 View 如果不设置LayoutParams 就 add进一个viewgroup类型 它的LayoutParams 是由 父viewgroup generateDefaultLayoutParams函数 决定的。
  • 类型强转的注意点 强转前加 if xxx instanceof xx的校验,典型问题: 兼容包下的控件getContext不能强转为Activity(布局文件写入控件,activity继承AppCompatActivity ) 追溯View第二个构造函数发现context是LayoutInfalte传来的,发现是LayoutInflater.from传来的,发是phoneWindow传来的 发现newPhoneWindow(Activity) ,这样按理说view的context本身就是activity,可是报错说是 tintContextWrapper
  • activity在做动画的时候,页面的绘制是暂停的,或者只是绘制几帧。调用一个方法可以让其在动画过程中不暂停绘制。 反射调用ViewRootImpl 中的 setDrawDuringWindowsAnimating(true) 在onAttachedToWindow后`调用(api 19及以上)类似的可以有:
   private boolean sInited = false;private Method msetDrawDuringWindowsAnimatingMethod;@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2 && Build.VERSION.SDK_INT< 24) {Object viewRootImpl = ((Activity)getContext()).getWindow().getDecorView().getParent();if (!sInited) {try {msetDrawDuringWindowsAnimatingMethod = viewRootImpl.getClass().getMethod("setDrawDuringWindowsAnimating", boolean.class);} catch (NoSuchMethodException e) {e.printStackTrace();}if (msetDrawDuringWindowsAnimatingMethod != null) {try {msetDrawDuringWindowsAnimatingMethod.invoke(viewRootImpl, true);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}sInited = true;}}}
复制代码
  • 优化View的inflate 如果你发现创建某个View的inflate很耗时,或者是measure和layout很耗时,你就只有采用类似这样的方式来优化它

耗时的工作完成的,把addViewInLayout之类的post到主线程就行了。 只有被添加到View树上的时候才可能会绘制,刚inflate出来的View没有被添加到View树上,所以不会进行measure和layout。measure是耗时的,如果在线程中执行,它就会减少主线程的卡顿,最后再添加到View树上,并且不用触发requestLayout。相当于异步加载view 使用场景:比如进入一个页面开启网络加载一段内容,当网络数据回来了就刷新页面,如果这个页面是列表,那么如果是正在滑动的时候刷新页面就会卡顿,这时就可以使用这种方式来进行优化。

  • 利用aapt解析apk信息

aapt dump badging demo.apk |grep version

aapt的其他参数,也比较使用,比如向apl中插入文件,删除文件,这个和unzip的效果是一样一样的。过去没用appt时,我们修改apk信息经常用zip/unzip,现在用appt也可以搞定,还能避免有的系统没有安装zip/unzip的问题

aapt a demo.apk test.txt

  • Activity被销毁分为两种:1. Activity对象被从ActivityThread中移除了,这时只是把java对象置null,如果你其他地方还持有该对象,这个activity是不会被释放的。 2. Activity所在的进程被回收,那它所有的资源都被回收了。只会有一些可序列化的数据被保存。

  • 以下条件webview可以关闭硬件加速

   //mModelNumber = Build.MODEL;
复制代码
  • 获取GPU刷新帧率

可以利用Looper的log机制和添加全局控件来自己实现那个柱状图。

  • 列表优化思路 1.item中不能使用任何xml,包括xml的drawable;2.减少View个数层级降低过度绘制;3.自己实现TextView,系统的TextView(特别是android 7.0以下系统)性能太烂。

  • anr adb shell ls /data/anr/

    adb pull /data/anr/traces.txt ~/Desktop

  • Handler中一段泄漏风险检测的代码
public Handler(Callback callback, boolean async) {if (FIND_POTENTIAL_LEAKS) {final Class<? extends Handler> klass = getClass();if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());}}mLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException("Can't create handler inside thread that has not called Looper.prepare()");}mQueue = mLooper.mQueue;mCallback = callback;mAsynchronous = async;}
复制代码

该思想可用于多种自测内存泄漏的场景。

  • 使用递归时,留意函数栈是否会爆
  • 线程池的大小经验值设置:(其中N为CPU的个数)

如果是CPU密集型应用,则线程池大小设置为N+1, 如果是IO密集型应用,则线程池大小设置为2N+1

如果一台服务器上只部署这一个应用并且只有这一个线程池,那么这种估算或许合理,具体还需自行测试验证。但是,IO优化中,这样的估算公式可能更适合:最佳线程数目 =((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目因为很显然,线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。下面举个例子:比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到: ((0.5+1.5)/0.5)*8=32。这个公式进一步转化为:最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目

掌阅群分享技术点收集(app性能优化专攻)相关推荐

  1. Android APP性能优化

    转载自:https://www.cnblogs.com/qwangxiao/p/8727229.html Android APP性能优化(最新总结) 导语 安卓大军浩浩荡荡,发展已近十个年头,技术优化 ...

  2. Android APP性能优化(一)

    Android APP性能优化(最新总结) 安卓大军浩浩荡荡,发展已近十个年头,技术优化日异月新,如今Android 8.0 Oreo 都发布了,Android系统性能已经非常流畅了.但是,到了各大厂 ...

  3. 秋色园QBlog技术原理解析:性能优化篇:打印页面SQL,全局的SQL语句优化(十三)...

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...

  4. Android App 性能优化系列结语篇

    Android App 性能优化系列结语篇 原文出处:http://gold.xitu.io/post/581f4ad667f3560058a33057 关于Android App的优化, 从第一篇的 ...

  5. Android App性能优化系列

    Android App性能优化系列 关于Android App的优化,从第一篇的计划开始,到内存优化的系列文结束,不知不觉近三个月的时间,写了十五六篇相关的博文,算是对自己的知识的一个系统化,也希望能 ...

  6. Android App 性能优化总结

    Android App 性能优化系列结语篇 转发自:http://blog.lmj.wiki/2016/11/06/app-opti/app_opt_summary/#more 关于Android A ...

  7. 秋色园QBlog技术原理解析:性能优化篇:用户和文章计数器方案(十七)

    2019独角兽企业重金招聘Python工程师标准>>> 上节概要: 上节 秋色园QBlog技术原理解析:性能优化篇:access的并发极限及分库分散并发方案(十六)  中, 介绍了 ...

  8. 秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五)...

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...

  9. WP7 App性能优化(8):检测应用程序性能(Ⅰ)

    有很多方法监视应用程序的性能并检测性能问题.检测内存占用是其中之一.也可以启用重绘区域着色和视图缓存,从而可视化的监视相关资源的使用情况.也可以打开帧频计数器使其在Windows Phone 7模拟器 ...

最新文章

  1. Enhanced-RCNN: 一种高效的比较句子相似性的方法 |​WWW 2020
  2. 12306架构到底是不是国内最牛逼的架构
  3. oracle 创建 触发,Oracle 创建触发器
  4. python、numpy,keras,tensorflow等函数用法积累(持续更新)
  5. 润飞rf1800支持解密吗_《密逃2》新一期来袭:还是你期待的样子吗?
  6. 【渝粤题库】国家开放大学2021春2786初级西方经济学题目
  7. 3打开db文件_sqlite库学习(3)为什么sqlite3_open会失败
  8. c语言编译器手机版显示错误,C语言编译器的错误信息
  9. 2019年8月9日 下午6:06:12 BD5613F5-0BE7-44DF-B231-CCC87
  10. 微型计算机usb接口通常串行,usb是串行接口吗_串行接口和并行接口有什么区别...
  11. Matlab实现雷达波位编排
  12. Java log2x函数的实现
  13. 解决多旅行商(MTSP)的分组遗传算法(GGA-SS)
  14. 三星s8 android版本,三星S8有几个版本?三星S8和三星S8+(plus)各个版本详细区别对比评测...
  15. 网络 4.0 防火墙概述
  16. java SSM项目基础(day 5)[实现用户添加功能(注册)]
  17. 乌镇论剑:张朝阳的四张牌=两横两纵
  18. 爬虫系列(四)--全站爬取
  19. qt小项目 代码实现简易的QQ聊天 对话框的界面实现
  20. 基恩士 sw1000 或2000(理论是通用)usb转RS232 USB60FW 驱动

热门文章

  1. Maven之(九)依赖关系
  2. C语言书籍阅读-读书笔记--高质量程序设计指南》--C/C++,林锐
  3. mysql命令查看表内容
  4. 你真的了解Linux(Deepin)的软件商店吗?(内附极力推荐的软件)
  5. 文件夹加密超级大师 v13.10 是什么
  6. Qt开发-QT Widgets
  7. MySQL联合索引原理解析
  8. C语言 日期转时间戳
  9. matlab 图像处理技术
  10. 再谈P2P技术:网络拓扑结构、核心技术分析