进度对话框未显示在屏幕上

4

我根据Mayank的答案来编辑我的代码,但在displayMsg()方法开始之前没有显示任何已输入的消息..我应该说MethodTest()是用nfc启动的,在onNewIntent(Intent 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>

3
int value= obj.doInBackground(msg); 的意思是调用 obj 对象的 doInBackground(msg) 方法并将结果赋值给整型变量 value。请参考 AsyncTask 来正确实现 AsyncTask。 - ρяσѕρєя K
这并不重要。我只是为了确保DisplayMsg被执行,并创建一个时间以便能够看到对话框。 - Fatemeh
5
请使用 obj.execute(""); 替换 int value= obj.doInBackground(msg);,并检查 ProgressDialog 是否正在显示。 - ρяσѕρєя K
如果你想等待异步任务执行完成,可以在调用异步任务时添加“.get”方法,但不建议这样做,因为界面会冻结直到结果返回。 - Manohar
obj.execute("")无法工作。我在"onProgressUpdate"处设置了断点,但我发现当Method1()完成时,onProgressUpdate被调用。为什么呢? - Fatemeh
显示剩余4条评论
4个回答

3
请记住,AsyncTasks 最好用于短时间操作(最多几秒钟)。
尽量学习更多关于 AsyncTask 的内容,并且在您的代码中有许多错误。
1.不要手动调用 doInBackground() 方法。 dc.doInBackground(totalMsg); // 错误
2.DisplayMsg() 方法被多次调用,每次都会创建一个 DisplayMsgClass 实例。 DisplayMsgClass dc = new DisplayMsgClass(); // 错误
3.在未初始化 textView 的情况下调用 textView.setText("Hello !!!"),会导致空指针异常。
请注意: 不要在同一实例上多次调用 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线程,而不会阻塞任何一个线程。

谢谢你回答我。不好意思,我不明白。我应该在doInBackground(Params...)中调用onProgressUpdate(Progress...)而不是publishProgress(Progress... values)吗?你能给我代码更改吗? - Fatemeh
1
我使用nfc。它调用新的意图方法,在这个方法中我调用了test方法。我找不到任何解决方案,所以使用了异步任务。如果您有解决我的问题的方法,请告诉我。我只想在调用方法之前显示消息。 - Fatemeh
我相信 onNewIntent(Intent) 方法在UI线程上被调用,这意味着你可以直接在该方法中修改TextView,而不必使用AsyncTask。 - Doris Liu
如果你的意思是在调用setText(...)时更改屏幕上的内容,那是不可能的。基本上你必须等待屏幕再次刷新(以60Hz频率)才能看到新的内容。实际上,你不会注意到它不是即时的,就像在游戏中使用控制器移动角色一样,直到电视再次刷新(也大多在60Hz),你才会看到他们移动,但你不会注意到延迟。 - Doris Liu
我可以使用进度条吗?并且在上面设置改变的文本吗? - Fatemeh
显示剩余5条评论

1
尝试下面的代码。
private int DisplayMsg(String msg) {
    totalMsg += msg;
    DisplayMsgClass dc = new DisplayMsgClass();
    dc.runner.execute(totalMsg);
}

希望它能够工作

:)GlbMP


对不起,但是dc中的runner未定义。我写了dc.onPostExecute(totalMsg); 但是当在onPostExecute(String result)方法中执行textv.setText(result);时,TextView内容没有改变:( 为什么需要进度条?它是做什么用的? - Fatemeh

0

在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是什么?它有什么用?我根据你的帖子编辑了我的代码,但是没有再显示任何消息。 - Fatemeh
这是一个示例,基本上在该示例中,我们从服务器获取数据(以JSON形式),并将其显示到TextView中。您必须根据自己的要求进行修改。 - Mayank Sharma
我编辑了我的代码。我添加了TextView并将编辑后的代码再次放入问题中。在displaymsg()方法中调用dc.doInBackground(totalMsg)后,只有doInBackground被调用并返回,而TextView中没有任何内容显示。我不应该在doInBackground方法中调用publishProgress吗? - Fatemeh
我加载UI,然后创建一个新的Intent并调用MethodTest()。我能在这个新的Intent中改变TextView的值吗? - Fatemeh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接