国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

thread - Android 主線程更新UI問題

瀏覽:121日期:2024-08-20 15:52:30

問題描述

本人使用了OKGO的框架, 下載文件,在下載之前創(chuàng)建一個(gè) 等待框,在更新進(jìn)度的回調(diào)中,更新等待框的百分比, 可是爆了如下錯(cuò)誤!thread - Android 主線程更新UI問題

通過LOG 發(fā)現(xiàn) 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() { //文件下載時(shí),可以指定下載的文件目錄和文件名 @Override public void onSuccess(File file, Call call, Response response) {// file 即為文件數(shù)據(jù),文件保存在指定目錄L.i('成功: ');if (dialog != null && dialog.isShowing()) dialog.dismiss();startUpdate(file); } @Override public void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) {//這里回調(diào)下載進(jìn)度(該回調(diào)在主線程,可以直接更新ui)L.i('(內(nè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(); }}); }

問題解答

回答1:

你使用的是MVP架構(gòu),在Presenter中不應(yīng)該操作View中的控件,而你在Presenter中操作了Dialog這個(gè)控件。所以正確的做法應(yīng)該是下面的:

Interface View{ void showDialog(); void updateDialog(int count); void dismissDialog(); void showError(); void dismissError();}class Presenter{ View view; public Presenter(View view){ this.view=view; } public void setDownloadUrl(String url){ OkGo.get(url)// .tag(this)// .execute(new FileCallback() { //文件下載時(shí),可以指定下載的文件目錄和文件名@Overridepublic void onSuccess(File file, Call call, Response response) { // file 即為文件數(shù)據(jù),文件保存在指定目錄 view.dismissDialog();} @Overridepublic void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) { view.update((int)progress);} @Overridepublic void onError(Call call, Response response, Exception e) { super.onError(call, response, e); view.dismissDialog(); view.showError();} }); } } 回答2:

你已經(jīng)打印出downloadProgress()方法執(zhí)行的環(huán)境不是UI線程,那么你把

dialog.setMessage('正在下載文件......' + (int) (progress * 100) + '%');

的執(zhí)行放在UI線程就可以了.

runOnUiThread(new Runnable() { @Override public void run() {dialog.setMessage('正在下載文件......' + (int) (progress * 100) + '%'); }});

||-------------------------補(bǔ)充 -------------------------||

我剛剛也打印了log,在ui線程和子線程中:

03-03 15:20:54.592 30842-30842/com.didikee.commondependence E/test: Out-->ThreadName: main id: 103-03 15:20:54.592 30842-30891/com.didikee.commondependence E/test: Inner-->ThreadName: main id: 807

主線程的id是1,子線程的id是807,他們的名稱都是main,而線程的名稱是可以指定的:

public Thread(String name) {//這是指定線程名稱的構(gòu)造函數(shù)init(null, null, name, 0); }

而線程的id卻是內(nèi)部生成的,不可以手動(dòng)指定,也就是說線程的名稱展示成什么并沒有說服力,id才是唯一,兩個(gè)id不一樣就不是同一線程,與主線程id不一樣那不一樣的那個(gè)就不是主線程,題主不知道糾結(jié)什么,可以去看Thread類的源碼:

tid = nextThreadID();....private static synchronized long nextThreadID() {return ++threadSeqNumber; }回答3:

下載任務(wù)執(zhí)行在UIThread將會(huì)阻塞界面,為了不影響應(yīng)用體驗(yàn),我們都會(huì)在異步線程當(dāng)中執(zhí)行下載任務(wù),而異步線程中執(zhí)行的回調(diào)自然是在異步線程了。Android中最常用的線程通訊機(jī)制是Handler:

Handler mHandler = new Handler(Looper.getMyLooper()); handler.post(new Runnable(){@Overridevoid run(){//在這里更新ui就好了} })

相關(guān)文章:
主站蜘蛛池模板: 日韩区 | 一级做a毛片免费视频 | 亚洲视频播放 | 天堂精品高清1区2区3区 | 久久精品视 | 精品无码三级在线观看视频 | 成人免费视频国产 | 夜精品a一区二区三区 | 国产成人亚洲精品久久 | 亚洲精品不卡午夜精品 | 日本女人在线观看 | 欧美成人极品怡红院tv | 国产三级国产精品国产国在线观看 | 免费看a视频 | 欧美成人午夜毛片免费影院 | 成人爱做日本视频免费 | 欧美整片在线观看 | 亚洲美女性视频 | 国产在线a| 亚洲视频男人的天堂 | 国产成人高清精品免费观看 | 中文字幕一区日韩在线视频 | 99在线在线视频免费视频观看 | 天天澡天天碰天天狠伊人五月 | 国产特黄特色一级特色大片 | 一区二区不卡久久精品 | 欧美6699在线视频免费 | 99精品视频一区在线观看miya | 午夜三级理论在线观看视频 | 港台三级在线观看 | 不卡一区二区在线观看 | 国产精品成人影院 | 国产一区二区在线看 | 91免费看片 | 一区二区三区网站在线免费线观看 | 96精品视频在线播放免费观看 | 国产成人无精品久久久 | 国产一区在线免费观看 | 美女三级黄 | 欧美日韩精品一区二区三区视频播放 | 日韩欧美在线看 |