没有调用AsyncTask onPostExecute

时间:2015-02-04 16:31:16

标签: android android-activity android-asynctask widget

我有一个带TextView的简单小部件。一个TextView应该显示从网页获取的信息,我正在使用它来实现它:

private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {

        // params comes from the execute() call: params[0] is the url.
        try {
            return downloadUrl(urls[0]);
        } catch (IOException e) {
            return getString(R.string.srv_dwn);
        }
    }
    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) {
        widgetText1 = result;
    }
}

从活动中调用DownloadWebpageTask,如下所示:

    DownloadWebpageTask downloadWebpageTask = new DownloadWebpageTask();
    Context context = this;
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
    ComponentName thisWidget = new ComponentName(context, Widget.class);

    ConnectivityManager cm =
            (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();

    if (netInfo != null && netInfo.isConnected())
    {
        remoteViews.setViewVisibility(R.id.widgettext1, View.VISIBLE);
        netInfo = cm.getActiveNetworkInfo();
        widgetText2 = netInfo.getTypeName();

        downloadWebpageTask.execute("http://checkip.amazonaws.com/");

        remoteViews.setTextViewText(R.id.widgettext1, widgetText1);
        remoteViews.setTextViewText(R.id.widgettext2, widgetText2);
        appWidgetManager.updateAppWidget(thisWidget, remoteViews);
    }
    else
    {
        remoteViews.setTextViewText(R.id.widgettext1, widgetText1);
        remoteViews.setViewVisibility(R.id.widgettext1, View.GONE);
        remoteViews.setTextViewText(R.id.widgettext2, getString(R.string.tbl_no_connection));
        appWidgetManager.updateAppWidget(thisWidget, remoteViews);
    }

此变量在我的Activity类中定义,应显示AsyncTask的结果,但不显示。

public String widgetText1 = "initialtext";

逐步调试表明,onPostExecute永远不会被调用,TextView中的文字仍然是'initialtext'。

第二次TextView根据需要进行更新,因为它不涉及AsyncTask

包括DownloadWebpageTask在内的类似代码在我的主要活动中运行良好。

3 个答案:

答案 0 :(得分:0)

您所做的只是更新String变量。您应该使用setText EditText方法进行更新。所以在onPostExecute中执行以下操作:

@Override
protected void onPostExecute(String result)
{
    yourEditText.setText(result);
}

答案 1 :(得分:0)

来自AsyncTask的

execute()方法在后台运行,所以当你调用它时,你的活动中的代码会继续执行,因为无法知道execute()方法需要多长时间才能完成: / p>

downloadWebpageTask.execute("http://checkip.amazonaws.com/");

remoteViews.setTextViewText(R.id.widgettext1, widgetText1);

所以,第二行是在调用onPostExcute()之前执行的,此时,wigetText1仍然是&#34; initialtext&#34;值。

你应该直接从onPostExecute()方法更新小部件(如@Willis所说),它保证在页面请求完成后更新它。

如果您需要使TextView或其他任何内容可见,请在onPostExecute()方法中执行。

但实际上,为了更新主要活动中的小部件,它们必须对AsyncTask可见,并将其声明为Activity类的内部类,如下所示:

public class myActivity extends Activity {

//Declare the TextView as a instance variable in your activity
public TextView widgetText1;

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash_screen);
       //Find your widget in the layout to avoid NullPointerException    when the AsynTask try to update it.
       widgetText1 = findViewById(R.id.some_id);
    }

//Inner class myTask
private class myTask extends AsyncTask<String, Void, String>{

        @Override
        protected String doInBackground(String... urls) {
            //some code
            return result;
        }

        @Override
        protected void onPostExecute(String result) {
           widgetText1.setText(result);
        }
    }
}

请注意,这样,您必须为要创建网页请求的每个活动创建一个新的AsynTask,但这里有一个关于如何创建可重用AsyncTask的参考。

Extracting out your AsyncTasks into separate classes makes your code cleaner

答案 2 :(得分:0)

我已切换到Service而不是Activity,但我认为可以在两种情况下实施解决方案。

我在Service类中创建了一个方法:

public void setIPWidget(String result)
{
    Context context = this;
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    ComponentName thisWidget = new ComponentName(context, Widget.class);

    remoteViews.setTextViewText(R.id.widgettext1, result);
    appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}

在onPostExecute中,我只需使用获得的结果调用该方法:

    @Override
    protected void onPostExecute(String result) {
        setIPWidget(result);
    }

比我想象的要简单。