本人使用了OKGO的框架, 下载文件,在下载之前创建一个 等待框,在更新进度的回调中,更新等待框的百分比, 可是爆了如下错误!
通过LOG 发现 UI线程ID 不一样
是什么问题? 求大神解决,以下是源码~!
public void setDownloadUrl(String url) {
if (TextUtils.isEmpty(url))
return;
if (dialog == null) {
dialog = new ProgressDialog(mainViewImpl.getContext());
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
dialog.setMessage("正在下载文件...");
dialog.setMax(100);
dialog.setTitle("软件更新");
}
dialog.show();
L.i("(外)线程ID: " + Thread.currentThread().getId());
OkGo.get(url)//
.tag(this)//
.execute(new FileCallback() { //文件下载时,可以指定下载的文件目录和文件名
@Override
public void onSuccess(File file, Call call, Response response) {
// file 即为文件数据,文件保存在指定目录
L.i("成功: ");
if (dialog != null && dialog.isShowing())
dialog.dismiss();
startUpdate(file);
}
@Override
public void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
//这里回调下载进度(该回调在主线程,可以直接更新ui)
L.i("(内)线程ID: " + Thread.currentThread().getId());
dialog.setMessage("正在下载文件......" + (int) (progress * 100) + "%");
}
@Override
public void onError(Call call, Response response, Exception e) {
super.onError(call, response, e);
L.i("失败: ");
if (dialog != null && dialog.isShowing())
dialog.dismiss();
}
});
}
你使用的是MVP架構,在Presenter中不應該操作View中的控件,而你在Presenter中操作了Dialog這個控件。
所以正確的做法應該是下面的:
你已經印出
downloadProgress()
方法执行的环境不是UI线程
,那麼你把的執行放在
UI
線程就可以了.||-------------------------補充--------------------- ----||
我剛剛也印了log,在ui線程和子線程中:
主執行緒的id是1,子執行緒的id是807,他們的名稱都是main,而執行緒的名稱是可以指定的:
而線程的id卻是內部生成的,不可以手動指定,也就是說線程的名稱展示成什麼並沒有說服力,id才是唯一,兩個id不一樣就不是同一線程,與主線程id不一樣那不一樣的那個就不是主線程,題主不知道糾結什麼,可以去看
Thread
類的源碼:下載任務執行在UIThread將會阻塞介面,為了不影響應用程式體驗,我們都會在非同步執行緒當中執行下載任務,而非同步執行緒中執行的回呼自然是在非同步執行緒了。
Android中最常用的執行緒通訊機制是Handler: