Rumah > Soal Jawab > teks badan
本人使用了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();
}
});
}
PHP中文网2017-04-18 09:15:26
Anda menggunakan seni bina MVP Anda tidak seharusnya mengendalikan kawalan dalam Paparan dalam Penyampai, tetapi anda mengendalikan kawalan Dialog dalam Penyampai.
Jadi pendekatan yang betul hendaklah seperti berikut:
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() { //文件下载时,可以指定下载的文件目录和文件名
@Override
public void onSuccess(File file, Call call, Response response) {
// file 即为文件数据,文件保存在指定目录
view.dismissDialog();
}
@Override
public void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
view.update((int)progress);
}
@Override
public void onError(Call call, Response response, Exception e) {
super.onError(call, response, e);
view.dismissDialog();
view.showError();
}
});
}
}
ringa_lee2017-04-18 09:15:26
Anda telah mencetak bahawa persekitaran di mana kaedah downloadProgress()
dilaksanakan bukan UI线程
, kemudian anda meletakkan
dialog.setMessage("正在下载文件......" + (int) (progress * 100) + "%");
Hanya letakkan pelaksanaan pada urutan UI
.
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.setMessage("正在下载文件......" + (int) (progress * 100) + "%");
}
});
||-----------------------Suplemen----- - -----||
Saya baru sahaja mencetak log, dalam utas ui dan sub-utas:
03-03 15:20:54.592 30842-30842/com.didikee.commondependence E/test: Out-->ThreadName: main id: 1
03-03 15:20:54.592 30842-30891/com.didikee.commondependence E/test: Inner-->ThreadName: main id: 807
Id utas utama ialah 1, id sub-utas ialah 807, kedua-dua nama mereka adalah utama, dan nama utas boleh ditentukan:
public Thread(String name) {
//这是指定线程名称的构造函数
init(null, null, name, 0);
}
ID utas dijana secara dalaman dan tidak boleh dinyatakan secara manual, dengan kata lain, nama utas itu tidak meyakinkan . Mereka tidak sama dengan utas utama Jika id berbeza, maka yang berbeza bukanlah utas utama. Anda boleh melihat kod sumber Thread
kelas:
tid = nextThreadID();
....
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
ringa_lee2017-04-18 09:15:26
Pelaksanaan tugas muat turun dalam UIThread akan menyekat antara muka Untuk tidak menjejaskan pengalaman aplikasi, kami akan melaksanakan tugas muat turun dalam urutan tak segerak dan panggilan balik yang dilaksanakan dalam utas tak segerak secara semula jadi dalam urutan tak segerak.
Mekanisme komunikasi benang yang paling biasa digunakan dalam Android ialah Pengendali:
Handler mHandler = new Handler(Looper.getMyLooper());
handler.post(new Runnable(){
@Override
void run(){
//在这里更新ui就好了
}
})