android handler多线程,Android Handler多线程技术 个人心得

这里有一篇详细介绍的文章:http://www.111cn.net/sj/android/95458.htm在进行解析URL往app中加载图片时,我首先引发了android.os.NetworkOnMainException的异常,原因在于在主线程中进行了网络请求的操作(真的是太菜了~),一般来说这种操作会导致UI线程堵塞,从而引起极差的用户体验,所以一般都是在子线程中异步加载。然而还有一个坑是,若要加载图片,必定会引发修改UI的操作(ImageView),但我们又知道更新UI的操作必须在UI线程或者说主线程中进行,所以综合下来我们考虑Handler通信的方式(其实AsyncTask也一样)来完成这个功能。

那么这里我们需要利用Handler同时完成主线程子线程的信息互换:主线程要把从EditText输入的URL的String发送给子线程去网络请求,子线程处理之后要把相应的bitmap传回给主线程来更新UI。主线程给子线程传递信息很简单,因为自身有默认的MessageQueue,无需调用Looper.prepare()以及Looper.loop()方法来维护MessageQueue,自动轮询。所以,在主线程中初始化的Handler就直接通过子线程发送过来的Message的what,通过switch-case判断来完成对应的功能。那么在子线程中,需要相应的操作来完成消息队列的轮询,并且在自己的线程中初始化自己的handler,同时Looper.prepare()才能把这个Handler同自己绑定,以实现传输信息的作用。

那么由于是个人心得,Handler内部机制就不多说啦,直接上代码配合注释希望能让你看懂!

public class MainActivity extends AppCompatActivity {

private EditText editText;

private Button preview_btn;

private Button post_btn;

private ImageView image;

private Bitmap bitmap;

private String path;

private PreviewThread previewThread;

private PostThread postThread;

/**

* 主线程的Handler对象,更新UI

*/

private Handler myHandler = new Handler(){

@Override

public void handleMessage(Message msg) {

switch(msg.what){

case 1:

image.setImageBitmap((Bitmap) msg.obj);

break;

case 2:

image.setImageBitmap((Bitmap) msg.obj);

break;

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

editText = (EditText) findViewById(R.id.edit);

preview_btn = (Button) findViewById(R.id.preview);

post_btn = (Button) findViewById(R.id.post);

image = (ImageView) findViewById(R.id.image);

/*

千万不要忘记打开线程!!

*/

previewThread = new PreviewThread();

previewThread.start();

postThread = new PostThread();

postThread.start();

/**

* 在对应的按钮事件中,我们发送给子线程path,也就是主线程与子线程通信

*/

preview_btn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

path = editText.getText().toString();

if (path.equals("")) {

setDialog("preview-operation denied.");

} else {

Message msg = new Message();

msg.obj = path;

previewThread.myHandler1.sendMessage(msg);

}

}

});

/**

* 在对应的按钮事件中,我们发送给子线程path,也就是主线程与子线程通信

*/

post_btn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

path = editText.getText().toString();

if (path.equals("")) {

setDialog("Post-operation denied.");

} else {

Message msg = new Message(); //也可以选用obtainMessage()那个方法

msg.obj = path; //直接装载path

postThread.myHandler2.sendMessage(msg); //发送给子线程

}

}

});

// post_btn.setEnabled(false);

}

/**

*弹窗提醒

*/

public void setDialog(String msg) {

new AlertDialog.Builder(MainActivity.this)

.setTitle("Warning")

.setMessage(msg)

.setNegativeButton("Okay",

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialogInterface, int i) {

}

}).show();

}

/**

* 预览,加载图片网络请求的子线程,拥有自己独立的handler以收发信息

* 在哪个线程中初始化Handler,这个Handler就是谁的,不过还需要跟Looper绑定才能完成收发信息

*/

class PreviewThread extends Thread{

private Handler myHandler1;

@Override

public void run() {

Looper.prepare();

myHandler1 = new Handler(){

@Override

public void handleMessage(Message msg) {

String path = (String) msg.obj;

URL httpUrl = null;

try {

httpUrl = new URL(path);

HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();

connection.connect();

bitmap = BitmapFactory.decodeStream(connection.getInputStream());

// post_btn.setEnabled(true);

Message toMain = new Message();

toMain.obj = bitmap; //直接把bitmap向上转型,赋给obj以完成信息装载

toMain.what = 1; //设置what以便于主线程Handler的switch-case

myHandler.sendMessage(toMain); //发送给谁就引用谁的sendMessage()

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

};

Looper.loop(); //启动消息循环

}

}

/**

* 设置背景的子线程,与上面的子线程类似不再赘述

*/

class PostThread extends Thread{

private Handler myHandler2;

@Override

public void run() {

Looper.prepare();

myHandler2 = new Handler() {

@Override

public void handleMessage(Message msg) {

String path2 = (String) msg.obj;

URL httpUrl = null;

try {

httpUrl = new URL(path2);

HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();

connection.connect();

MainActivity.this.setWallpaper(connection.getInputStream());

bitmap = null;

post_btn.setEnabled(true);

Message toMain = new Message();

toMain.obj = bitmap;

toMain.what = 2;

myHandler.sendMessage(toMain);

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

};

}

}

}

f143dfece61ca28224e95f637a4428f6.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值