【问题标题】:Progress Dialog not show on screen进度对话框不显示在屏幕上
【发布时间】:2016-11-08 08:26:23
【问题描述】:

我根据亲爱的 Mayank'answer 编辑了我的代码,但它没有显示在方法开始之前在 displayMsg() 方法中作为输入发送的任何消息。我应该说 MethodTest() 是使用 nfc 和方法 onNewIntent(Intent意图)

@Override
protected void onNewIntent(Intent intent) {
   MethodTest();
    ..............

}

public void MethodTest() {
    DisplayMsg("method 1 is running");
    Method1();

    DisplayMsg("method 2 is running");
    Method2();

    DisplayMsg("method 3 is running");
    Method3();

}

private int DisplayMsg(String msg) {
    totalMsg += msg;
    DisplayMsgClass dc = new DisplayMsgClass();
    dc.doInBackground(totalMsg);
}

private class DisplayMsgClass extends AsyncTask<String, Integer, String> {

    @Override
    protected void onPreExecute() {
         textView.setText("Hello !!!");
        progressBar = (ProgressBar) findViewById(R.id.progressBar1);
        progressBar.setVisibility(View.VISIBLE);
        super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);

    }

    @Override
    protected String doInBackground(String... Messages) {


        return Messages[0];
    }

    @Override
    protected void onPostExecute(String result) {
        progressBar.setVisibility(View.INVISIBLE);

        textView.setText(result);
    }
}

在我的布局中:

<LinearLayout>
<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"
    android:id="@+id/progressBar1"
    />
 <TextView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:id="@+id/textv1"
  android:hint="AppletPass"
  android:gravity="center"/>
 </LinearLayout>

【问题讨论】:

  • int value= obj.doInBackground(msg); 是什么意思?请参阅AsyncTask 了解正确的 AsyncTask 实现
  • 这并不重要。我把它放在确保 DisplayMsg 被执行并创建一个可以看到对话框的时间
  • 好的,使用obj.execute(""); 代替int value= obj.doInBackground(msg); 并检查ProgressDialog 是否显示
  • 如果你想等到异步任务执行,在调用异步任务时添加.get,但不推荐,因为UI会冻结直到得到结果
  • obj.execute("") 不工作。我在“onProgressUpdate”上设置了断点,但我看到 Method1() 何时完成,onProgressUpdate 被调用。为什么?

标签: android nfc-p2p


【解决方案1】:

请记住,AsyncTasks 应该理想地用于短操作(最多几秒钟)。

尝试了解更多关于 AsyncTask 的内容,你的代码中有很多错误

  1. 不要手动拨打doInBackground()

    dc.doInBackground(totalMsg); // 错误

  2. 多次调用DisplayMsg(),每次都会创建一个DisplayMsgClass类的新实例

    DisplayMsgClass dc = new DisplayMsgClass(); // 错误

  3. onPreExecute()
    textView.setText("Hello !!!"); // NullPointerException。 textView.setText() 在没有初始化的情况下被调用。

注意

不要在同一个实例上多次调用AsyncTask.execute()
例如:

DisplayMsgClass displayMsgClass = new DisplayMsgClass();  
displayMsgClass.execute();  
displayMsgClass.execute(); //Error, IllegalStateException  

将根据您的实现向您展示一个基本演示,您可以根据自己的方式简单地对其进行修改。

public void MethodTest() {

    // execute task
    new DisplayMsgClass().execute("Download now");
}

/*
public void MethodTest() {
    DisplayMsg("method 1 is running");
    Method1();

    DisplayMsg("method 2 is running");
    Method2();

    DisplayMsg("method 3 is running");
    Method3();

}

private int DisplayMsg(String msg) {
    totalMsg += msg;
    DisplayMsgClass dc = new DisplayMsgClass();
    dc.doInBackground(totalMsg);
}
*/

private class DisplayMsgClass extends AsyncTask<String, Integer, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        // retrieve the widgets
        progressBar = (ProgressBar) findViewById(R.id.progressBar1);
        textView = (TextView) findViewById(R.id.textv1);


        textView.setText("Download initialized");
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    @Override
    protected String doInBackground(String... Messages) {

        // read commands
        String command = Messages[0];
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Download completed";
    }

    @Override
    protected void onPostExecute(String result) {

        //invoked on the UI thread after the background computation finishes
        progressBar.setVisibility(View.INVISIBLE);
        textView.setText(result);
    }
} 

【讨论】:

    【解决方案2】:

    您看到在 if(...) 末尾调用 onProgressUpdate(Progress...) 的原因是因为 publishProgress(Progress... values) 将消息发布到内部处理程序,该内部处理程序稍后会处理该消息以更新进度。换句话说,publishProgress(Progress... values) 不会同步调用 onProgressUpdate(Progress...) 在此处查看实现:https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/AsyncTask.java#L649

    这是必要的,因为 publishProgress(Progress... values) 预计会从 doInBackground(Params...) 调用,它位于 AsyncTask 的 工作线程 上,而 onProgressUpdate(Progress...) 发生在 UI 线程 以便 UI 可以反映进度变化。通过在 UI 线程上向处理程序发布消息,进度信息可以从工作线程同步到 UI 线程,而不会阻塞任一线程。

    【讨论】:

    • 谢谢你回答我。 wxcuse我我不明白。我应该在doInBackground(Params ...)中调用onProgressUpdate(Progress ...)而不是publishProgress(Progress ... values)吗?可以给我修改代码吗?
    • 我不清楚您为什么选择使用 AsyncTask:AsyncTask 专为在工作线程上运行的昂贵后台任务而设计,以使 UI 线程免于执行可能导致丢帧的耗时任务。 MethodTest() 应该运行在 UI 线程还是后台线程上?
    • 我使用 nfc。它调用新的意图方法,在这个方法中我调用方法测试。我找不到任何解决方案并使用了异步任务。如果您对我的问题有解决方案,请给我。我只想在调用方法之前显示消息
    • 我相信 onNewIntent(Intent) 是在 UI 线程上调用的,这意味着您可以直接在该方法中修改 TextView 而不是使用 AsyncTask。
    • 我编辑了我的代码 private void DisplayMsg(String msg) { totalMsg +=msg; textv.setText(msg);在调试模式下我得到 txtv.gettesxt() ,文本视图有新消息,但在 ui 上它不显示新消息。它的信息没有改变
    【解决方案3】:

    试试下面的代码

    private int DisplayMsg(String msg) {
        totalMsg += msg;
        DisplayMsgClass dc = new DisplayMsgClass();
        dc.runner.execute(totalMsg);
    }
    

    希望能成功

    :)GlbMP

    【讨论】:

    • 对不起,dc 中的 runner 是未定义的。我写了 dc.onPostExecute(totalMsg);但是当 textv.setText(result);在方法 onPostExecute(String result) textview content not changed 中执行:(为什么需要进度条?它有什么作用?
    【解决方案4】:

    在 xml 布局中创建进度条并默认设置其可见性并创建代码作为示例

    // AsyncTask .

        private class DownloadWebPageTask extends AsyncTask<String, Integer, String> {
    
        @Override
        protected void onPreExecute() {
            //textView.setText("Hello !!!");
            progressBar = (ProgressBar) findViewById(R.id.progressBar1);
            progressBar.setVisibility(View.VISIBLE);
            super.onPreExecute();
        }
    
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
    
        }
    
        @Override
        protected String doInBackground(String... urls) {
            String response = "";
            for (String url : urls) {
                DefaultHttpClient client = new DefaultHttpClient();
                HttpGet httpGet = new HttpGet(url);
                try {
                    HttpResponse execute = client.execute(httpGet);
                    InputStream content = execute.getEntity().getContent();
    
                    BufferedReader buffer = new BufferedReader(new InputStreamReader(
                            content));
                    String s = "";
                    while ((s = buffer.readLine()) != null) {
                        response += s;
                    }
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return response;
        }
    
        @Override
        protected void onPostExecute(String result) {
            progressBar.setVisibility(View.INVISIBLE);
            textView.setText(result);
        }
    }
    

    【讨论】:

    • 谢谢你回答我。请问什么是textview?为什么要使用它?我根据您的帖子编辑了我的代码。但不再显示任何消息
    • 它是一个示例,所以基本上在该示例中,我们从服务器(在 json 中)获取数据并将其显示到 Textview 中。你必须根据你的要求修改它
    • 我编辑了我的代码。我放置了文本视图,并再次将我编辑的代码置于问题之中。调用后 dc.doInBackground(totalMsg);在 displaymsg() 方法中。只有 doInBackground 被调用并返回,文本视图中没有任何显示。我不应该在 doInBackground 方法中调用 publishProgress 吗?
    • 我加载 ui 然后创建一个新意图并调用 MethodTest()。我可以在这个新意图中更改 textview'value 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 2011-01-09
    相关资源
    最近更新 更多