异步任务的进度条旋转器无法工作

3
我的问题是,当我点击“点击”按钮调用我的API时,它应该在调用API时显示我的进度条(旋转动画)。但是,我的应用程序会在不到一秒的时间内冻结,然后在完成调用后短暂地显示我的加载旋转器(它只是闪烁)。
以下是我的代码。
private ProgressBar spinner;
public View onCreateView(...)
{
    spinner = (ProgressBar) view.findViewById(R.id.progressBar1);
    spinner.setVisibility(View.GONE);
    ...
}



private class MyTask extends AsyncTask<String, Void, Void> {

    String pageContent = "";
    DataOutputStream wr;


    @Override
    protected void onPreExecute() {
        spinner.setVisibility(View.VISIBLE);
    }

    @Override
    public Void doInBackground(String... params) {

        requestResult.setSuccess(false);
        HttpURLConnection connection;

        try {
            String url = "myURL";

            //I only call my Api here. I delete rest so this won't bother you

            requestResult.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        JsonParser parser = new JsonParser();
        //Same here i delete nonimportant 

        MyResponse = new Gson().fromJson(jsonContent, MyResponse.class);
        done();
        spinner.setVisibility(View.GONE);
    }

}

我尝试过不同的方法,但总是会出现一秒钟的卡顿,然后我的加载动画就会闪烁,接着API返回的内容就显示出来了。

请问您能帮我解决这个问题吗?

以下是我的XML文件。

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll_view_send"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:minWidth="25px"
        android:minHeight="25px">
        <ProgressBar
            android:id="@+id/progressBar1"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_below="@id/buttonSend"
            android:visibility="gone"/>
    </RelativeLayout>
</ScrollView>

代码不足以查看细节,但如果您想要更新一个Spinner,您需要在onProgressUpdate API中执行,因为它在UI线程上运行。同时,请确保您不会在doInBackground和其他方法中共享变量,而是使用参数传递值。 - Francesc
你在模拟器中进行测试吗? - Gueorgui Obregon
其他代码只是调用一个API而已,没别的了,或者我错了? onProgressUpdate不是用来查看进度吗?我只需要一个无限旋转的Spinner。我只需要启动这个spinner并停止它。 是的,我使用参数传递我的值。我通过params [0]访问它们... - Rok
是的,我在模拟器中进行了测试。 - Rok
1
不要设置可见性,尝试使用 show()dismiss() - Balu SKT
显示剩余3条评论
2个回答

2
尝试使用下面的代码片段。它不需要在布局文件中声明spinner。
AsyncTask<String, String, String> asyncObject =
new AsyncTask<String, String, String>() {
    ProgressDialog progDailog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progDailog =
                new ProgressDialog(Activity.this);
        progDailog.setMessage("Loading");
        progDailog.setCancelable(false);
        progDailog.show();
    }

    @Override
    protected String doInBackground(String... urls) {
        //Do background stuff here
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        progDailog.cancel();
        //Do post background stuff here.
    }
};
asyncObject.execute(null, null, null);

谢谢您的帮助,但是和之前一样。就好像这段代码被跳过了,在onPostExecute中执行了。 - Rok
不要设置旋转器的可见性,尝试使用显示和取消函数。 - Balu SKT

1
请尝试此可用示例,将spinner传递给您的MyTask,如下所示:
private class MyTask extends AsyncTask<String, Void, Void> {

    String pageContent = "";
    DataOutputStream wr;

    private final ProgressBar progress;

    public MyTask(final ProgressBar progress) {
        this.progress = progress;
    }


    @Override
    protected void onPreExecute() {
        progress.setVisibility(View.VISIBLE);
    }

    ...

    @Override
    protected void onPostExecute(Void result) {
        JsonParser parser = new JsonParser();
        //Same here i delete nonimportant 

        MyResponse = new Gson().fromJson(jsonContent, MyResponse.class);
        done();
        progress.setVisibility(View.GONE);
    }
}

然后调用new MyTask(progress).execute();

编辑: 在您的问题中,您提到在调用MyTask时手机会冻结... 请按照以下步骤避免在AsyncTask中冻结用户界面:

  1. 不要使用new MyTask().get()来调用MyTask
  2. 尝试将这部分MyResponse = new Gson().fromJson(jsonContent, MyResponse.class); done();移到doInBackground中,因为这可能很耗费时间。

希望能对您有所帮助!


我非常感谢你的帮助,但这仍然不起作用,和之前一样。parent和textview变量是怎么回事?我收到“变量可能未初始化”的错误提示。 - Rok
我删除了未使用的变量,你在哪里看到“变量可能未初始化”? - Gueorgui Obregon
我以前也遇到过这个问题。就好像这段代码在onPreExecute中被跳过,而在onPostExecute中执行了。无论我怎么做,结果总是一样的。 - Rok
我编辑了我的回答,主要问题不是Spinner,而是你的手机为什么会冻结,使用AsyncTask不应该出现这种情况。 - Gueorgui Obregon
太好了!非常感谢g2o。是的,我调用了MyTask().get(),我永远不会想到这个。谢谢! - Rok

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