ym——Android从零开始(15)(Activity启动模式、ANR异常、Handler)(新)

转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!


Activity启动模式任务堆栈

Activity中的任务是与用户交互的一组Activity的集合,Activity会被按打开顺序安排在一个堆栈里。

任务栈:并不是ActivityActivity的引用(内存地址)


standard 标准模式

每次激活Activity时都会创建Activity,并放入任务栈中

默认模式

1.jpg 


singleTop 独享堆栈顶端

如果在任务的栈顶正好存在该Activity的实例,就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)

如:浏览器的书签

2.png 


singleTask 独享任务堆栈

如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中

如:浏览器的主页

3.png 


singleInstance单例

在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity的实例存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中

如:通话界面

4.png 

总结

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 开启子线程改变显示。

//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() 发送一个消息对象到消息队列;

发送、接受、处理消息消息队列;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值