时间:2021-05-19
okHttp用于android的http请求。据说很厉害,我们来一起尝尝鲜。但是使用okHttp也会有一些小坑,后面会讲到如何掉进坑里并爬出来。
首先需要了解一点,这里说的UI线程和主线程是一回事儿。就是唯一可以更新UI的线程。这个只是点会在给okHttp填坑的时候用到。而且,这个内容本身在日常的开发中也经常用到,值得好好学一学。
okHttp发起同步请求
第一个列子是一个同步请求的例子。
private void performSyncHttpRequest() { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://.okhttpdemo D/###okHttp: Not Main Thread。所以要在主线程中更新view只好想别的办法了。在worker线程里更新主线程会抛异常。一般来说有这么几个方法在子线程里更新view。
在子线程更新UI线程
一、Activity的runOnUiThread方法
在Activity中有这么一个方法runOnUiThread。这个方法需要一个Runnable实例作为参数。
MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { Log.d(TAG, "code: "); Toast.makeText(MainActivity.this, String.valueOf(response.code()), Toast.LENGTH_SHORT).show(); } });二、View的post方法
View的post方法也是一样,扔一个Runnable的实例进去。然后就在主线程执行了。Toast肯定是没有这个方法的。
MainActivity.this.mView.post(new Runnable() { public void run() { Log.d("UI thread", "I am the UI thread"); }});三、其他
1.用Handler,这个前面的okHttp同步请求的例子可以用。
2.AsyncTask, 有两个方法可以在主线程中执行:onProgressUpdate和onPostExecute。这里我们并不是要更新进度,所以考虑的是后一个方法。
private class BackgroundTask extends AsyncTask<String, Void, Bitmap> { protected void onPostExecute(Bitmap result) { Log.d("UI thread", "I am the UI thread"); }}综合以上,更新UI线程的方法里最后说到的Handler方法和AsyncTask都太重。尤其是AsyncTask。还要继承实现一堆的方法之后才可以能达到目的,同时还和我们要用的okHttp的使用方法很多不兼容的地方。
所以我们只考虑前面的两种。但是两种方法其实是不一样的。当然,这里并不是说方法的名字不一样。我们来看看android的源代码,这两个方法是如何实现的。
public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } } // mHandler.post(action); 之post方法的实现 public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }方法runOnUiThread最后会调用Handler的sendMessageDelayed。但是这里只delay了0。也就是方法传到这里的时候会立即执行runOnUiThread的参数Runnable实例会立即执行。
下面看看View的post方法:
public boolean post(Runnable action) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.post(action); } // Assume that post will succeed later ViewRootImpl.getRunQueue().post(action); return true; }一般会执行的是ViewRootImpl.getRunQueue().post(action);。也就是Runnable的实例只是添加到了事件队列中,按照顺序执行。并不一定会立即执行。
我们探讨了那么多,最后就使用runOnUiThread来更新界面,也就是方法一了。
call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { final String errorMMessage = e.getMessage(); if (Looper.getMainLooper().getThread() == Thread.currentThread()) { Log.d(TAG, "Main Thread"); } else { Log.d(TAG, "Not Main Thread"); } MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, errorMMessage, Toast.LENGTH_SHORT).show(); } }); } @Override public void onResponse(Call call, final Response response) throws IOException { if (Looper.getMainLooper().getThread() == Thread.currentThread()) { Log.d(TAG, "Main Thread"); } else { Log.d(TAG, "Not Main Thread"); } MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { Log.d(TAG, "code: "); Toast.makeText(MainActivity.this, String.valueOf(response.code()), Toast.LENGTH_SHORT).show(); } }); }});无论请求成功还是失败,都弹出一个Toast。用MainActivity.this.runOnUiThread在UI线程中弹出这个Toast。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了Android实现在子线程中更新Activity中UI的方法。分享给大家供大家参考,具体如下:在Android平台下,进行多线程编程时,经常需要在
前言相信每位Android开发者们都知道更新UI只能在主线程中进行,若是在子线程执行任务后需要更新UI,则需要借助handler跳转到主线程中。以下介绍几种操作
AsyncTask不仅方便我们在子线程中对UI进行更新操作,还可以借助其本身的线程池来实现多线程任务。下面是一个使用AsyncTask来实现的多线程下载例子。0
Handler的定义:主要接受子线程发送的数据,并用此数据配合主线程更新UI.解释:当应用程序启动时,Android首先会开启一个主线程(也就是UI线程),主线
一、Handler的定义:主要接受子线程发送的数据,并用此数据配合主线程更新UI.解释:当应用程序启动时,Android首先会开启一个主线程(也就是UI线程),