另一个线程中的某些方法无法在Android中执行

时间:2013-07-16 09:09:57

标签: java android multithreading

问题

单击“注销”按钮后,有时不会执行某些操作。在下面的代码中,有时似乎不会执行hideTabBar()showAuth(),但有时会执行它们。为什么呢?

源代码

MainActivity.java

public void selectLogout(View view) {
    AlertDialog.Builder mAlertDialogBuilder = new AlertDialog.Builder(this);
    mAlertDialogBuilder.setTitle("Logout").setMessage("Are you sure you wanna logout?");
    mAlertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });
    mAlertDialogBuilder.setPositiveButton("Logout", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            mWebview.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mWebview.loadUrl(WEB_BASE + LOGOUT_TAG);
                    btnSlide.performClick();
                    hideTabBar();
                    showAuth();
                }
            }, 500);
        }
    });
    mAlertDialogBuilder.show();
}

activity_main.xml

android:onClick="selectLogout"用于将onClick回调函数绑定到注销按钮。

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="100dp"
    android:background="@color/button_state_resource"
    android:clickable="true"
    android:onClick="selectLogout" >

    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="20dp"
        android:src="@drawable/icon_logout" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="120dp"
        android:text="Logout" />

</RelativeLayout>

1 个答案:

答案 0 :(得分:0)

请记住,任何与UI相关的更改都必须在UI线程上进行。因此,如果您尝试在后台线程中更改UI,则可能会抛出错误。要解决此问题,您可以使用可以将作业发布到UI线程的Handler按顺序运行。

示例:

private Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
    //....some stuff
    //initialize Handler
    handler = new Handler();
}


public void selectLogout(View view) {
    AlertDialog.Builder mAlertDialogBuilder = new AlertDialog.Builder(this);
    mAlertDialogBuilder.setTitle("Logout").setMessage("Are you sure you wanna logout?");
    mAlertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
        }
    });
    mAlertDialogBuilder.setPositiveButton("Logout", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            mWebview.postDelayed(new Runnable() {
                @Override
                public void run() {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            // update UI
                            mWebview.loadUrl(WEB_BASE + LOGOUT_TAG);
                            btnSlide.performClick();
                            hideTabBar();
                            showAuth();
                        }
                    });
                }
            }, 500);
        }
    });
    mAlertDialogBuilder.show();
}