开发者

Dialog in separate thread

I'm fairly new at threading so this could be a pretty n00by question.. (: I've got a thread running in a separate class to my main activity this all works well, I'm able to access methods on my main activity from the thread using handler.Post(new Runnable() {... and this all works well until I try to call a dialog which requires user input.

This is the method for the dialog:

public boolean displayConfirm(String message, String positiveButton, String negativeButton, final displayConfirmer onOnClick) {
    AlertDialog.Builder builder = new AlertDialog.Builder(ISyncCRMActivity.this);
    builder.setMessage(message);
    builder.setCancelable(false);
    builder.setPositiveButton(positiveButton, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface arg0, int arg1) {
            onOnClick.onClick(true);
        }
    });
    builder.setNegativeButton(negativeButton, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface arg0, int arg1) {
            onOnClick.onClick(false);
        }
    });
    AlertDialog dialog = builder.create();
    dialog.show();
    return bool;
}


private boolean bool;
public interface displayConfirmer {
        public void onClick(boolean result);
    }

As you can see you pass it a message for the dialog to display and a yes, no button text, then it returns wherever the user clicked yes (true) or no (false), with this I'm using a interface for the onClick(). All of this allows me to use this code to execute it...

displayConfirm("Is this a dialog?", "Yes", "No", new ISyncCRMActivity.displayConfirmer() {
                public void onClick(boolean result) {
                    // TODO Auto-generated method stub
                    Toast.makeText(ISyncCRMActivity.this, result ? "Yes" : "No", Toast.LENGTH_LONG).show();
                }
            });

This will wait until the user has clicked yes or no before moving on in the code which is e开发者_JS百科xactly what I need, but in another thread.

So in my separate thread this is what I'm doing:

handler.post(new Runnable() {
                    public void run() {
                        iSyncCRMActivity.displayConfirm("Is this a dialog?", "Yes", "No", new ISyncCRMActivity.displayConfirmer() {
                            public void onClick(boolean result) {
                                if (result) dialog = true;
                                else dialog = false;
                            }
                        });
                    }
                });
             if (dialog) {
                 //clicked yes
             } else {
                //clicked no
             }

As you can see, I want to invoke the dialog on the UI thread and then handle the response on the separate thread.

How am I able to achieve this? Is this even achievable?! Any help would be much appreciated (: Thanks!

Edit:

this is the error:

    07-20 11:04:35.782: ERROR/global(16201): Deprecated Thread methods are not supported.
07-20 11:04:35.782: ERROR/global(16201): java.lang.UnsupportedOperationException
07-20 11:04:35.782: ERROR/global(16201):     at java.lang.VMThread.stop(VMThread.java:85)
07-20 11:04:35.782: ERROR/global(16201):     at java.lang.Thread.stop(Thread.java:1379)
07-20 11:04:35.782: ERROR/global(16201):     at java.lang.Thread.stop(Thread.java:1344)
07-20 11:04:35.782: ERROR/global(16201):     at com.millennium.isynccrm.Classes.TcpClient.disconnect(TcpClient.java:55)
07-20 11:04:35.782: ERROR/global(16201):     at com.millennium.isynccrm.Classes.SyncClient.stopSync(SyncClient.java:73)
07-20 11:04:35.782: ERROR/global(16201):     at com.millennium.isynccrm.Classes.SyncClient.recieveMessage(SyncClient.java:236)
07-20 11:04:35.782: ERROR/global(16201):     at com.millennium.isynccrm.Classes.TcpClient$1.run(TcpClient.java:34)
07-20 11:04:35.782: ERROR/global(16201): [ 07-20 11:04:35.782 16201:0x3f54 F/dalvikvm ]
07-20 11:04:35.782: ERROR/global(16201): Exception!!! threadid=10: thread exiting with uncaught exception (group=0x4001d810)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201): FATAL EXCEPTION: Thread-12
07-20 11:04:35.812: ERROR/AndroidRuntime(16201): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.view.ViewRoot.checkThread(ViewRoot.java:2806)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.view.ViewRoot.requestLayout(ViewRoot.java:594)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.view.View.requestLayout(View.java:8125)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.view.View.requestLayout(View.java:8125)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.view.View.requestLayout(View.java:8125)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.view.View.requestLayout(View.java:8125)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.view.View.requestLayout(View.java:8125)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.widget.TextView.checkForRelayout(TextView.java:5378)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.widget.TextView.setText(TextView.java:2688)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.widget.TextView.setText(TextView.java:2556)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at android.widget.TextView.setText(TextView.java:2531)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at com.millennium.isynccrm.ISyncCRMActivity.updateCurentTask(ISyncCRMActivity.java:282)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at com.millennium.isynccrm.Classes.SyncClient.stopSync(SyncClient.java:74)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at com.millennium.isynccrm.Classes.SyncClient.recieveMessage(SyncClient.java:236)
07-20 11:04:35.812: ERROR/AndroidRuntime(16201):     at com.millennium.isynccrm.Classes.TcpClient$1.run(TcpClient.java:34)


I believe you are waiting for your dialog boolean to be set before you proceed to your next line of code. There are a number of ways to do this and I suggest you read up on Java concurrency tutorials here. Below is quick solution to get things working but I am not sure that it is the best as I am unfamiliar with android development. However, I thought the main point of dialogs in Android is that they are asynchronous (Why don't you put what you want to happen next in your callback rather than getting another thread to wait?).

A new class which keeps a record of whether yes or no has been pressed:

public class WaitingDialog implements Runnable {
        volatile boolean finished;
        volatile boolean dialog;
        String message;
        String button1;
        String button2;

    public WaitingThread(String message, String button1, String button2) {
        this.button1 = button1;
        this.button2 = button2;
        this.message = message;
        finished = false;
    }

    @Override
    public void run() {
        iSyncCRMActivity.displayConfirm(message, button1, button2, new ISyncCRMActivity.displayConfirmer() {
            public void onClick(boolean result) {
                if (result) dialog = true;
                else dialog = false;
                finished = true;
            }
        });
    }

    public boolean isFinished() {
        return finished;
    }

    public boolean getDialog {
        return dialog;
    }
}

And your existing code using this new class:

WaitingDialog waitingDialog = new WaitingDialog("Is this a dialog?", "Yes", "No");

handler.post(waitingDialog);
//Wait here for onclick to be called before you proceed
while(!waitingDialog.isFinished())

if (waitingDialog.getDialog()) {
    //clicked yes
} else {
    //clicked no
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜