android性能优化-Handler

一.概述

    很多APP都要做性能优化,但是做性能优化首先得要发现问题,本本篇文章将教会你怎么发现android卡顿的地方。

 

二.如何发现卡顿点

    卡顿一般都是线程处理消息卡顿,那我们就看看如何发现某一个消息卡顿吧,看这里前建议先了解一下Handler的原理,我就不再介绍了。
我们每一个线程都会有一个loop,这个负责循环处理消息,我们直接上代码吧:

/**
 * Run the message queue in this thread. Be sure to call
 * {@link #quit()} to end the loop.
 */
public static void loop() {
    final Looper me = myLooper();
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }
    final MessageQueue queue = me.mQueue;

    // Make sure the identity of this thread is that of the local process,
    // and keep track of what that identity token actually is.
    Binder.clearCallingIdentity();
    final long ident = Binder.clearCallingIdentity();

    for (;;) {
        Message msg = queue.next(); // might block
        if (msg == null) {
            // No message indicates that the message queue is quitting.
            return;
        }

        // This must be in a local variable, in case a UI event sets the logger
        final Printer logging = me.mLogging;
        if (logging != null) {
            logging.println(">>>>> Dispatching to " + msg.target + " " +
                    msg.callback + ": " + msg.what);
        }

        final long traceTag = me.mTraceTag;
        if (traceTag != 0) {
            Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
        }
        try {
            msg.target.dispatchMessage(msg);
        } finally {
            if (traceTag != 0) {
                Trace.traceEnd(traceTag);
            }
        }

        if (logging != null) {
            logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
        }

        // Make sure that during the course of dispatching the
        // identity of the thread wasn't corrupted.
        final long newIdent = Binder.clearCallingIdentity();
        if (ident != newIdent) {
            Log.wtf(TAG, "Thread identity changed from 0x"
                    + Long.toHexString(ident) + " to 0x"
                    + Long.toHexString(newIdent) + " while dispatching to "
                    + msg.target.getClass().getName() + " "
                    + msg.callback + " what=" + msg.what);
        }

        msg.recycleUnchecked();
    }
}

重点在这:

            // This must be in a local variable, in case a UI event sets the logger
            final Printer logging = me.mLogging;
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

            final long traceTag = me.mTraceTag;
            if (traceTag != 0) {
                Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
            }
            try {
                msg.target.dispatchMessage(msg);
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }

            if (logging != null) {
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }
我们能看到在分发消息前后会打印一个log。这里可以告诉我们这个消息处理了多长时间。你可以让你的每一个loop都实现println方法。可以看看我写的一个例子:
public class MainActivity extends Activity implements Printer {
    String TAG = "Activity";
    long mesgStart = 0;
    long mesgEnd = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Handler handler = new MyHandler();
        getMainLooper().setMessageLogging(this);
        Message message = new Message();
        message.what = 1;
        handler.sendMessage(message);
    }


    @Override
    public void println(String x) {
        if (x.contains("Dispatching")) {
            mesgStart = System.currentTimeMillis();
            Log.d(TAG, x);
        } else if (x.contains("Finished")) {
            mesgEnd = System.currentTimeMillis();
            Log.d(TAG, "Message processing time : " + (mesgEnd - mesgStart) + "ms         " + x);
        }

    }
}

class MyHandler extends Handler {
    String TAG = "Activity";
    public void handleMessage(Message msg) {
        Log.d(TAG, "handleMessage msg is!!!!!!!!!!!!!!!!!!! " + msg.what);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

代码很简单,就是实现了println方法,并把它set到mainLooper中,然后自己重写了一个hander,里边sleep 3s,我们运行代码看一下效果吧:

12-23 16:11:14.504 18882 18882 D Activity: >>>>> Dispatching to Handler (water.android.testapp.MyHandler) {9f39ff9} null: 1
12-23 16:11:14.504 18882 18882 D Activity: handleMessage msg is!!!!!!!!!!!!!!!!!!! 1
12-23 16:11:17.505 18882 18882 D Activity: Message processing time : 3001ms         <<<<< Finished to Handler (water.android.testapp.MyHandler) {9f39ff9} nul

三.总结

    性能优化的难点主要是发现问题,其次是解决问题的过程。这里就教会大家一个发现问题的方法,APP开发的同学也可以通过这里来打点数据,看看自己APP每个方法的平均耗时时间,然后着重解决耗时长的消息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值