thread - Android 主线程更新UI问题
天蓬老师
天蓬老师 2017-04-18 09:13:26
0
3
1288

本人使用了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();
                    }
                });
    }
天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全員に返信(3)
洪涛

MVP アーキテクチャを使用しています。プレゼンターのビューでコントロールを操作する必要はありませんが、プレゼンターでダイアログ コントロールを操作します。
したがって、正しいアプローチは次のようになります:

リーリー
いいねを押す +0
左手右手慢动作

downloadProgress() メソッドが実行される環境が UI线程 ではないことを出力したので、

を入力します。 リーリー

の実行を UI スレッドに置くだけです。

リーリー

||--------------------------補足------- -----||

UI スレッドとサブスレッドでログを出力しました:

リーリー

メインスレッドの ID は 1、サブスレッドの ID は 807、それらの名前は両方ともメインであり、スレッドの名前を指定できます:

リーリー

スレッドの ID は内部で生成され、手動で指定することはできません。つまり、スレッドの名前は唯一のものです。2 つの ID が異なる場合、それらは同じスレッドではありません。それらはメインスレッドと同じではありません。ID が異なる場合、質問者は、Thread のソースコードを見てください。クラス:

リーリー
いいねを押す +0
左手右手慢动作

UIThread でダウンロード タスクを実行すると、インターフェイスがブロックされます。アプリケーション エクスペリエンスに影響を与えないように、ダウンロード タスクは非同期スレッドで実行されます。非同期スレッドで実行されるコールバックは、当然ながら非同期スレッド内にあります。
Android で最も一般的に使用されるスレッド通信メカニズムはハンドラーです:

リーリー
いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート