ANR的三种情况
1.主要类型按键或者触摸操作在特定时间(5秒)内无法完成
2.BroadcastReceiver在特定时间(10秒)内无法处理完成
3.小概率类型Service在特定时间内无法处理完成
子线程两种开启方法:
继承Thread:
自定义MyThread:
private class MyThread extends Thread { public MyThread(int i) {//构造函数 this.i = i; } private int i=0; @Override public void run() { super.run(); String s=Thread.currentThread().getName(); Log.d(TAG, "线程1启动了 "+s); } //这里可以 //自定义方法 }
启动方法:
Thread thread=new MyThread(1); thread.start();
实现Runnable接口
自定义MyThread1:
private class MyThread1 implements Runnable{ public MyThread1(int i) { this.i = i; } private int i=0; @Override public void run() { String s=Thread.currentThread().getName(); Log.d(TAG, "线程2启动了 "+s); } }
启动方法:
Runnable thread1= new MyThread1(1); new Thread(thread1).start();
线程的一些方法:
线程外部调用的一些方法:
thread.start();//启动线程
thread.join();//等待子线程结束, thread.join(millis);//加入参数就表示等待子线程多少时间
thread.isInterrupted();//中断子线程,回到就绪状态
线程内部调用的一些方法:
Thread.sleep(10);//线程休眠,阻塞线程 Thread.yield();//一个时间片完成后,交出cpu时间,时间无法指定,只有优先级比它高的线程可以使用这个时间,它则等待再次分配 Thread.interrupted();中断子线程,回到就绪状态
还有一些其他方法
如果希望明确地让一个线程给另外一个线程运行的机会:
调整各个线程的优先级
让处于运行状态的线程调用 Thread.sleep()方法
让处于运行状态的线程调用 Thread, yield()方法
让处于运行状态的线程调用另一个线程的join()方法
Handler:
使用Handler方式进行异步消息处理
主要由Message,Handler,MessageQueue,Looper四部分组成:
(1)Message,线程之间传递的消息,用于不同线程之间的数据交互。Message中的what字段用来标记区分多个消息,arg1、arg2 字段用来传递int类型的数据,obj可以传递任意类型的字段。
(2)Handler,用于发送和处理消息。其中的sendMessage()用来发送消息,handleMessage()用于消息处理,进行相应的UI操作。
(3)MessageQueue,消息队列(先进先出),用于存放Handler发送的消息,一个线程只有一个消息队列。一个消息队列可以有多个handle
(4)Looper,可以理解为消息队列的管理者,当发现MessageQueue中存在消息,Looper就会将消息传递到handleMessage()方法中,同样,一个线程只有一个Looper。一个Looper可以有多个handle
handler的用法:
主线程中Handler的用法:
在主线程中
private Handler handler;
handler=new Handler() { @Override public void handleMessage(Message msg) { //处理逻辑 } };
在子线程中
第一种方法:
Message message=new Message(); String ss="sdasd"; int i=1; message.what=i;//.what是用来发送int型 message.obj=ss;//.obj可以传递任意类型的字段。 handler.sendMessage(message);
第二种方法
Message message=handler.obtainMessage(); String ss="sdasd"; int i; message.what=1; message.obj=ss; message.sendToTarget();
子线程中Handler的用法:
在主线程中
private Handler handler;
第一种方法:
Message message=new Message(); String ss="sdasd"; int i=1; message.what=i;//.what是用来发送int型 message.obj=ss;//.obj可以传递任意类型的字段。 handler.sendMessage(message);
第二种方法
Message message=handler.obtainMessage(); String ss="sdasd"; int i; message.what=1; message.obj=ss; message.sendToTarget();
在子线程中
因为:
在非主线程中直接new Handler() 会报如下的错误: E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。
Looper.loop(); 让Looper开始工作,从消息队列里取消息,处理消息。
注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行
Looper.prepare();//在子线程中要先开启Looper handler1=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); //处理逻辑 } }; Looper.loop();