Android 多线程 (一)

来源:互联网 发布:美亚保险 淘宝 编辑:程序博客网 时间:2024/06/05 17:03

ANR问题

1、先认识一下多线程异常
如果在主线程里面处理的事情过多,在执行过程中,某一阶段执行的任务过多,就会阻塞在一点,这时阻塞的时间长就会弹出继续等待还是退出应用!

ANR : Application Not Responding ,应用无响应

1 、 (Activity) 按键或者触摸事件在特定时间内 (5 秒 ) 无响应,主要是在加载UI界面时阻塞2 、 BroadcastTimeout ,广播接收超时 (10 秒无响应 )3 、 ServiceTimeout, 服务中 (20 秒无响应 )// 常见的是前两种情况,第三种概率很小基本不存在

Thread+Handler

private void updateProgress() {        new Thread() {            @Override            public void run() {                while (progressBar.getProgress() < progressBar.getMax()) {                    int p = progressBar.getProgress() + 5;                    mHandler.obtainMessage(1, p).sendToTarget();                    try {                        Thread.sleep(200);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }.start();    }

Looper :负责线程中循环检测消息队列中是否有消息的一个对象,如果发现有消息,则移除消息给 Handler 处理

Handler : sendMessage postRunnable… 主要向它所关联的 Looper 所在的线程消息队列中压入消息对象,等到 Looper 发现消息移除消息出来然后给
handleMassage 方法处理

消息队列 MessageQueue :负责线程中消息的管理,先进先出

线程通讯机制
可以在子线程中通过 Looper 管理 Handler ,接收其他线程发来的消息

class A extends Thread {        A() {            super("线程A");        }        @Override        public void run() {            Log.e("m_tag", "启动");            //准备Looper            Looper.prepare();            //创建依赖于该线程Looper的Handler            aHandler = new Handler() {                @Override                public void handleMessage(Message msg) {                    Log.e("m_tag", "所在的线程" + getName() + "收到的消息" + msg.what);                    if (msg.what == 102) {                        //处理完事情停止Looper检测消息队列                        Looper.myLooper().quit();                    }                }            };            //启动Looper            Looper.loop();            Log.e("m_tag", "A线程结束");        }    }class B extends Thread {        @Override        public void run() {            Log.e("m_tag", "B启动--休眠2S");            try {                Thread.sleep(2000);            } catch (InterruptedException e) {                e.printStackTrace();            }            Log.e("m_Tag", "B线程发消息给A线程");            aHandler.sendEmptyMessage(101);            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            aHandler.sendEmptyMessage(102);        }    }

使用

new A().start();new B().start();

如果在其他线程中要关联主线程的 Looper 可以使用 Looper.getMainLooper() 得到 Looper 对象

mainHandler = new Handler(Looper.getMainLooper()){    @Override    public void handleMessage(Message msg) {        Log.e("m_tag", "所在的线程" + Thread.currentThread().getName()                + "收到的消息:" + msg.what);    }};

HandlerThread 的使用

HandlerThread t1 = new HandlerThread(" 线程 C");t1.start();// 基于 HandlerThread 创建 HandlercHandler = new Handler(t1.getLooper()){    @Override    public void handleMessage(Message msg) {        Log.e("m_tag", "所在的线程" + Thread.currentThread().getName()                + "收到的消息:" + msg.what);        Looper.myLooper().quit(); // 退出 Looper 的循环 , 结束线程    }};

异步任务

可以继承 AsynTask 类实现异步任务,继承时 AsyncTask 后面的 3 个参数表示传入的参数类型,更新的参数类型,返回值类型

class MyTask extends AsyncTask<Object,Integer,Boolean>{        //子线程执行的方法        @Override        protected Boolean doInBackground(Object... params) {            int startProgress = (Integer) params[0];            while(startProgress < progressBar.getMax()){                startProgress +=2;                //更新,发布更新信息                publishProgress(startProgress);                try {                    Thread.sleep(200);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            return true;        }        //接收更新方法,是doInBackground方法中使用publishProgress方法时执行的        @Override        protected void onProgressUpdate(Integer... values) {            int p = values[0];            progressBar.setProgress(p);        }        //接收结果,就是doInBackground方法return的内容        @Override        protected void onPostExecute(Boolean aBoolean) {            if (null != aBoolean && aBoolean){                Toast.makeText(MainActivity.this,"更新完毕",Toast.LENGTH_LONG).show();            }else {                Toast.makeText(MainActivity.this,"更新失败",Toast.LENGTH_LONG).show();            }        }    }

使用:

new MyTask().execute(10);
原创粉丝点击