解决UI主线程阻塞原因

了解进程和线程的区别,在进行耗时操作遇到阻塞时,学会线程阻塞时的处理方法。
当线程阻塞超过5秒时,会遭到系统的提示解决阻塞的问题的方法:

(1)创建一个新的进程
官方建议:不要阻塞UI进程;
不要在UI进程之外的其他线程中,对视图当中的组件进行设置。
//经典异常
Only the original thread that created a
view hierarchy can touch its views.
只有创建view的那个线程才能对其进行修改。

解决异常的方法:
(1)用post来解决。(弊端:代码复杂度增加了,
因为可读性差了,所以维护性也就差了)

(2)最佳的解决法案:用AsyncTask来解决。(例子
在test_thread实例里面)(其实这里并不是最佳,应该比较AsyncTask和handl机制的区别,这两种解决方案在不同场合下的应自己分析使用)

(3)用handle机制的解决方案:采用handle机制来实现子线程发送message通知主线程去改变UI组件。

代码如下:## 这个是上面的AsyncTask和post方案的比较的实例代码 ##

package com.example.test_thread;

import android.app.Activity;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
     private Button button2=null;//把button2设置成成员变量
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button1 = (Button) findViewById(R.id.button1);
        // TranslateAnimation是位移的动画效果
        TranslateAnimation animation = new TranslateAnimation(0, 150, 0, 100);
        animation.setRepeatCount(30);// 设置动画重复多少次
        animation.setDuration(3000);// 设置动画的效果时间
        button1.setAnimation(animation);
        button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(new OnClickListener() {
            // 当线程阻塞超过5秒时,会遭到系统的提示
            @Override
            // 这里的v其实就是Button2对象
            public void onClick(final View v) {/*
                // /用Thread.currentThread().getId()来进行观看post与
                // UI主线程是一致的
                System.out.println(Thread.currentThread().getId());
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("线程开始执行。。。。");
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        v.post(new Runnable() {
                            public void run() {
                                System.out.println("post开始执行。。。。"+
                            Thread.currentThread().getId());
                                TextView view = (TextView) v;// 用view来接收v
                                view.setText("" + 10);
                            }
                        });
                        System.out.println("线程结束执行。。。。");
                    }
                }).start();
            */
                new DownloadImageTask().execute();
                }
        });

    }

    private class DownloadImageTask extends AsyncTask<String,Void,Integer>{
        /**The system calls this to perform work in a worker thread and
         * delivers it the parameters given to AsyncTask.excute()
         */
        protected Integer doInBackground(String... urls) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int sum=10;
            return sum;
        }
        /**The system calls this to perform work in the UI thread and delivers
         * the result from doInBackground()
         */
        protected void onPostExecute(Integer sum){
            //把button2设置成成员变量就可以调用setText
            button2.setText(""+sum);
        }
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值