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



我的应用程序项目有问题,正如你在代码中看到的,我有一个异步任务,它应该检查互联网连接并从云中加载必要的数据。如果连接失败,我会显示一个alert对话框来传递错误消息。此警报对话框具有重试按钮,用于通过执行异步任务的新实例来重复整个过程。我还有一个TextView(txtRetry),它也做同样的事情。这个TextView是不可见的,只要用户不关闭alert对话框,它就应该保持原样。问题是,当用户单击alertdialog中的重试按钮时,它会启动新的异步任务,并以某种方式使我的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>

谢谢你的帮助!

您正在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);
}

之所以会发生这种情况,是因为您无法在后台线程中更改UI视图。

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

For example :
void doInBackground(...)
{
// myProgress is changed...
publishProgress(myProgress);
}
void onProgressChanged(Integer value)
{
if(value.intValue() == 0)
myTextView.setVisibility(View.Invisible);
}

如果您需要在二次启动中更改可见性,请在UI线程中执行操作

您的对话框有一个OnCancelListener()。这样,您就可以将文本视图的可见性更改为可见。然后在该框中的唯一按钮上,您调用它来取消,从而触发OnCancelListener();

如果您移除

alertDialog.cancel();

并离开

alertDialog.desponse();

您的对话框应该关闭,但不能调用OnCancelListener()。

最新更新