Android异步加载(UI刷新)

指切正题,为何要选择异步加载?

由于UI线程(也可叫主县城线程)负责处理用户输入事件(TP事件,显示事件等),直接与用户交互,如果UI线程阻塞,直接会影响用户的体验效果,严重的会报ANR错误。所以我们需要把耗时操作移出主线程,在子线程中进行处理。

下面罗列几种实现异步加载的方式。

传统JAVA方法实现异步

1.继承Thread类

代码如下

package UseThred;

public class TestThread extends Thread{
	public String behavior;

	
    public TestThread(String behavior){
        this.behavior = behavior;
    }

    @Override
    public void run() {
        System.out.println(behavior);
    }

}

实现如下:

package UseThred;

public class UseThread {

	public UseThread() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) {
		TestThread thread1 = new TestThread("行为1");
		TestThread thread2 = new TestThread("行为2");
	}
}


自定义一个类继承Thread类,在run()里面执行耗时操作,start()执行


2.实现Runnble接口

class TestRunnable implements Runnable {

	private String behavior;

	public TestRunnable(String behavior) {
		this.behavior = behavior;
	}

	@Override
	public void run() {
		System.out.println(behavior);
	}
}

public class UseThread {

	public UseThread() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) {

		TestRunnable runnable1 = new TestRunnable("runnable1");
		TestRunnable runnable2 = new TestRunnable("runnable2");
		TestRunnable runnable3 = new TestRunnable("runnable3");

		Thread t1 = new Thread(runnable1);
		Thread t2 = new Thread(runnable1);
		Thread t3 = new Thread(runnable1);

		t1.start();
		t2.start();
		t3.start();
	}

}

这种方式感觉繁琐一点,自定义类实现Runnable接口,然后加入new Thread,最后start(). 但是java中是单继承方式,需要实际的类进行操作,所以使用实现接口的方式较多一点。

当然我一般选择偷懒:

        new Thread(new Runnable() {
            @Override
            public void run() {
                //耗时操作执行
            }
        }).start();


Android异步

作为一个Android开发,怎么能忘了Android独有的异步加载方式呢?因为有时候我们需要在子线程能更新UI,这些方式就比较繁琐了。

先说一下Android使用传统Java线程方法异步并更新UI的方法

1.使用runOnUiThread

        new Thread() {
            public void run() {
                // 1.执行耗时操作
                runOnUiThread(new Runnable(){
                    @Override
                    public void run() {
                        // 2.更新UI
                        button_show.setText("refresh");
                    }
                });
            }
        }.start();

ps: runOnUiThread是Activity的方法,注意引用上下文对象。

2.post或者posrDelay

        new Thread() {
            public void run() {
                // 1.执行耗时操作 postDelay/post
                button.post(new Runnable() {
                    @Override
                    public void run() {
                        // 2.UI
                        button_show.setText("post");
                    }
                });
            }
        }.start();

3.Handler + Message或者Handler + Thread + Message

简单说就是主线程写一个Handler,子线程中通过handler传递消息。代码如下。

   Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    //拿到数据 ,更新UI
                    String data = (String)msg.obj;
                    button.setText(data);
                    break;
                default:
                    break;
            }
        }
    };

    private void setUI() {
        new Thread(new Runnable(){
            @Override
            public void run() {
                //  1.进行耗时操作
                //  2.传递数据
                mHandler.sendEmptyMessage(0);
                Message msg =new Message();
                msg.obj = "数据";//传送Object;  
                mHandler.sendMessage(msg);
            }
        }).start();
    }

4.AsyncTask

这是最普遍的用法之一了,无聊的面试官总会问你这个异步加载怎么实现,其实我想回答他,百度,然后CV大法进行面向搜索引擎开发。附上代码吧,也省的我以后百度了。

    private class MyTask extends AsyncTask<String, Integer, String> {
        //执行后台任务前做一些UI操作
        @Override
        protected void onPreExecute() {
            button.setText("loading...");
        }

        //执行后台任务(耗时操作),不可在此方法内修改UI
        @Override
        protected String doInBackground(String... params) {
            return null;
        }

        //更新进度信息
        @Override
        protected void onProgressUpdate(Integer... progresses) {
            progressBar.setProgress(progresses[0]);
            button.setText("loading..." + progresses[0] + "%");
        }

        //执行完后台任务后更新UI
        @Override
        protected void onPostExecute(String result) {
            button.setText(result);
        }

        //取消执行中的任务时更改UI
        @Override
        protected void onCancelled() {
            button.setText("cancelled");

        }
    }

下面说几个关于AnsysTask老生长谈的几个注意点:

1.必须在UI线程中创建异步任务的实例。
2.必须在UI线程中调用execute(Params... params)方法。
3.不要手动调用其中继承的方法。
4.不能在doInBackground(Params... params)中更改UI组件的信息。
5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。

猜你喜欢

转载自blog.csdn.net/ma598214297/article/details/80531863
今日推荐