执行新的AsyncTask实例会更改TextView可见性

时间:2014-03-04 17:32:39

标签: android android-asynctask textview android-alertdialog

我的app项目有问题,你可以在代码中看到我有一个asynctask,它应该检查互联网连接并从云中加载必要的数据。如果连接失败,我有一个alertdialog,它将显示为发送错误消息。此alertdialog具有重试按钮,通过执行异步任务的新实例来重复整个过程。我也有一个TextView(txtRetry),它也是这样做的。这个TextView是不可见的,只要用户没有关闭alertdialog它就应该保持这种状态。问题是当用户点击alertdialog中的重试按钮时,它会启动新的asynctask并且它以某种方式使我的TextView也可见,但它不应该。你有什么想法,可能导致这个问题......?

这是活动

public class InitActivity extends Activity {

private Context ctx;

    /* this textview should be invisible after
    the user clicks on the "retry" button in the alertdialog */
TextView txtRetry; 

private AlertDialog alertDialog;
private AlertDialog.Builder builder;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_init);

    ctx = this;
    txtRetry = (TextView) findViewById(R.id.btnRetry);
    txtRetry.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            txtRetry.setVisibility(View.INVISIBLE);
            new MyAsyncTask().execute((Void[]) null);
        }
    });

    Handler handler = new Handler();

    handler.postDelayed(new Runnable() {

        @Override
        public void run() {
            MyAsyncTask task = new MyAsyncTask();
            task.setTxtRetry(txtRetry);
            task.execute((Void[]) null);
        }

    }, 1000);

    this.initializeAlertDialog();
}

private void initializeAlertDialog() {
    builder = new AlertDialog.Builder(ctx);
    builder.setCancelable(true);
    builder.setTitle(R.string.ad_title);
    builder.setMessage(R.string.ad_msg);

            /* this is the retry button in the alertdialog */
    builder.setNeutralButton(R.string.btnRetry,
            new DialogInterface.OnClickListener() {

        public void onClick(DialogInterface dialog, int id) {
            alertDialog.cancel();
            alertDialog.dismiss();
            MyAsyncTask task = new MyAsyncTask();
            task.setTxtRetry(txtRetry);
            task.execute((Void[]) null);

        }
    });

    builder.setOnCancelListener(new OnCancelListener() {

        @Override
        public void onCancel(DialogInterface arg0) {
            txtRetry.setVisibility(View.VISIBLE);
        }
    });
}

private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

    private ProgressDialog pd;
    String title = getResources().getString(R.string.title_pd_connecting_to_the_server);
    String msg = getResources().getString(R.string.msg_pd_connecting_to_the_server);
    boolean success = false;        
    private TextView txtRet;

    @Override
    protected void onPreExecute() {
        pd = new ProgressDialog(ctx);
        pd.setTitle(title);
        pd.setMessage(msg);
        pd.setCancelable(false);
        pd.setIndeterminate(true);
        pd.show();
    }

    @Override
    protected Void doInBackground(Void... params) {

                    // connection to the server is simulated here...
        //TODO: Connect on the server...
        //TODO: get players count...

        try {
            //txtRet.setVisibility(View.INVISIBLE);
            success = false;
            Thread.sleep(3000);
        } catch (InterruptedException e) {

        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        pd.dismiss();
        pd.cancel();

        if(success) {
            Intent intent = new Intent(InitActivity.this, MainActivity.class);
            intent.putExtra("players", 4);
            startActivity(intent);
            finish();
        } else {
            alertDialog = builder.create();
            alertDialog.show();
        }
    }

    public void setTxtRetry(TextView txtRetry) {
        txtRet = txtRetry;
    }

}
}

正如您所看到的,我还尝试在AsyncTask类中设置TextView并在那里使用它,但它没有帮助......

这是activity_init布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
    android:id="@+id/logo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="@string/app_name"
    android:textColor="@android:color/holo_blue_dark"
    android:textSize="90sp" />

<TextView
    android:id="@+id/tm"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@id/logo"
    android:layout_toRightOf="@id/logo"
    android:text="@string/tm"
    android:textColor="@android:color/holo_blue_dark"
    android:textSize="12sp" />

<!-- this is the text view -->
<TextView
    android:id="@+id/txtRetry"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="16dip"
    android:clickable="true"
    android:text="@string/btnRetry"
    android:textColor="@android:color/holo_blue_dark"
    android:textSize="25sp"
    android:visibility="invisible" />

</RelativeLayout>

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

您在onClick中调用cancel(),然后调用Cancel侦听器并显示TextView。删除它,你应该很高兴。

public void onClick(DialogInterface dialog, int id) {
        alertDialog.cancel();
        alertDialog.dismiss();
        MyAsyncTask task = new MyAsyncTask();
        task.setTxtRetry(txtRetry);
        task.execute((Void[]) null);
}

答案 1 :(得分:0)

这是因为您无法在后台主题中更改 UI 视图

如果您想更改 TextView 可见性状态,请使用publishProgress方法并在onProgressChanged方法中设置可见性。

For example :

void doInBackground(...)
{
 // myProgress is changed...
 publishProgress(myProgress);
}

void onProgressChanged(Integer value)
{
    if(value.intValue() == 0)
        myTextView.setVisibility(View.Invisible);
}

如果您需要更改辅助启动中的可见性,请执行在UI线程中

答案 2 :(得分:0)

您的对话框中有一个OnCancelListener()。您可以将文本视图的可见性更改为可见。然后在那个框中你唯一的按钮,你要求它取消哪个触发OnCancelListener();

如果删除

alertDialog.cancel();

并离开

alertDialog.dismiss();

你的对话框没有关闭,但没有调用OnCancelListener()。