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.一个任务实例只能执行一次,如果执行第二次将会抛出异常。

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值