Android(安卓)Thread子线程和主线程的UI交互
16lz
2021-01-26
我们知道更新UI只能在主线程中,但是在日常应用中我们除了使用封装好的AsyncTask外大多会使用Thread+Handler的手法来实现子线程从网络获取数据,然后再修改主线程上的View视图,现在我们可以使用下面5种方法来实现线程间的UI交互.
1,认识Activity.runOnUiThread(Runnable)先上代码
public class MyActivity extends Activity { private final static String PIC_URL = "http://www.easyicon.net/api/resizeApi.php?id=1171895&size=128"; private ImageView picIv; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); picIv = (ImageView) findViewById(R.id.pic_iv); } /** * 获取图片的监听事件,此方法需要和xml布局中的button的 android:onClick="doRequest" * 属性名称一致并且为public类型不然会报一些问题 * @param view */ publicvoid doRequest(View view) { thread.start(); } Thread thread = new Thread(new Runnable() { @Override public void run() { final Bitmap bitmap = getBitmap(PIC_URL); if (bitmap != null){ MyActivity.this.runOnUiThread(new Runnable() { @Override public void run() { picIv.setImageBitmap(bitmap); } }); } } }); /** * 获取网络资源图片 * @param path 图片地址 * @return bitmap */ public static Bitmap getBitmap(String path) { InputStream is = null; try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); conn.setRequestMethod("GET"); is = conn.getInputStream(); if (conn.getResponseCode() == 200) { Bitmap bitmap = BitmapFactory.decodeStream(is); conn.disconnect(); return bitmap; } } catch (IOException e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } }
其中main.xml 的布局为
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="doRequest" android:text="获取图片"/> <ImageView android:id="@+id/pic_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher"/>LinearLayout>
AndroidManifest.xml添加权限:
<uses-permission android:name="android.permission.INTERNET"/>
2,了解View.post(Runnable)将MyActivity.this.runOnUiThread方法替换为
picIv.post(new Runnable() { @Override public void run() { picIv.setImageBitmap(bitmap); } });
3,使用View.postDelayed(Runnable, long)实现线程间的UI交互将上述方法改为
picIv.postDelayed(new Runnable() { @Override public void run() { picIv.setImageBitmap(bitmap); } },1*1000);//1*1000表示1s
4,学会Handler.post(Runnable)实现线程间的UI交互将上述方法改为
new Handler().post(new Runnable() { @Override public void run() { picIv.setImageBitmap(bitmap); } });
但由于我们是在子线程内部new的Handler所以会报这个异常:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
所以我们在线程外获取Handler对象即可Handler handler = new Handler();
然后改成下面的形式就哦了。
handler.post(new Runnable() { @Override public void run() { picIv.setImageBitmap(bitmap); } });
5,最后使用Handler.postDelayed(Runnable, long)实现线程间的UI交互将上述方法改为
handler.postDelayed(new Runnable() { @Override public void run() { picIv.setImageBitmap(bitmap); } },1*1000);
以上就是总结的5种方法在android子线程中更新UI的方法实现,如果有做的不对的地方希望指正
更多相关文章
- SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
- Android6.0来电流程
- android判断快捷方式是否已经创建的方法
- android 中ActivityUI装态保存
- 2018最新 Android(安卓)面试题总结(二)
- android部分控件应用解析
- android2.1之后appwidget的一些问题
- ContentProvider 学习之01
- android ImageView.getDrawingCache return NULL一点...