转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!
Activity启动模式任务堆栈
Activity中的任务是与用户交互的一组Activity的集合,Activity会被按打开顺序安排在一个堆栈里。
任务栈:并不是Activity是Activity的引用(内存地址)
standard 标准模式
每次激活Activity时都会创建Activity,并放入任务栈中
默认模式
如果在任务的栈顶正好存在该Activity的实例,就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)
如:浏览器的书签
如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中
如:浏览器的主页
singleInstance单例
在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity的实例存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中
如:通话界面
总结
Singletop:如果重复使用上一次的Activity,就重用。
SingleTask:如果使用已经实例化Activity,就重用,并且删除重用Activity前面的Activity,重用的Activity置顶任务栈。
SingleInstance:在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例。(调用Activity和重用Activity不在一个栈中)
SingleTop 、singleTask 、singleInstance 优化性能、重用Activity。
ANR异常
Application Not Responding应用程序没有响应
出现ANR的情况
主线程在5秒内没有响应输入事件(java中的main(),又名UI线程)
BroadcastReceiver 没有在10秒内完成返回
导致ANR的操作
在主线程内进行网络操作
在主线程内进行一些缓慢的磁盘操作
子线程不能操作显示。
所以使用Handler 开启子线程改变显示。
//Handler的作用:完成子线程和主线程的通讯
//主要接受子线程发送的数据, 并用此数据配合主线程更新UI.
public class MainActivity extends Activity {
public static final int INFO = 0;
private TextView tv_info;
//定义Handler对象
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case INFO:
int count = (Integer) msg.obj;
tv_info.setText(count+"");
break;
default:
break;
}
};
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv_info = (TextView) findViewById(R.id.tv_info);
}
public void start(View v){
//开启子线程进行运算
// new Thread(new MyThread()).start();
mHandler.post(new MyThread());
}
private class MyThread implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
int count = 0;
int i = 0;
while(i<=100){
count+=i++; //
SystemClock.sleep(200);
//改变TextView的显示
tv_info.setText(count+"");
//子线程不能操作显示:要不然就会出现
//android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
//所以在这种情况下,就必须使用Handler.
//发消息给主线程
//第一种方式
/* Message msg = new Message();
msg.what = INFO;
msg.obj = count;
//发送消息
mHandler.sendMessage(msg);*/
//第一种方式
/* Message msg = Message.obtain();
msg.what = INFO;
msg.obj = count;
//发送消息
mHandler.sendMessage(msg);*/
//第三种方式
// Message msg = mHandler.obtainMessage(INFO,count);
// msg.sendToTarget();
}
}
}
}
课后问题:
1.任务栈的作用是什么
Activity中的任务是与用户交互的一组Activity的集合,Activity会被按打开顺序安排在一个堆栈里。
2.Activity的四种启动模式
standard 标准模式
singleTop 独享堆栈顶端
singleTask 独享任务堆栈
singleInstance单例
3.Anr异常产生的原因
Application Not Responding应用程序没有响应
出现ANR的情况
主线程在5秒内没有响应输入事件
BroadcastReceiver 没有在10秒内完成返回
导致ANR的操作
在主线程内进行网络操作
在主线程内进行一些缓慢的磁盘操作
4.Handler的作用
Handler的作用:完成子线程和主线程的通讯
主要接受子线程发送的数据, 并用此数据配合主线程更新UI.
5.如何使用Handler发送消息
Handler中分发消息的一些方法
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
实例化Handler重写handleMessage方法
开启线程
准备一个线程。
线程体run():
Message msg = new Message(); // 得到Message对象
msg.what = INFO; // 定义类型
msg.obj = count; // 定义内容
mHandler.sendMessage(msg); // 发送 执行handleMessage()方法进行对发送的内容进行操作。
6.post()和sendMessage的区别
与Handler绑定的有两个队列,一个为消息队列,另一个为线程队列。Handler可以通过这两个队列来分别:
post() 将一个线程加入线程队列
启动、结束、休眠线程–线程队列;
sendMessage() 发送一个消息对象到消息队列;
发送、接受、处理消息–消息队列;