非UIスレッドからダイアログをポップアップします
-
09-10-2019 - |
質問
グループ指向のネットワークアプリを開発しています。問題は、私がグループに参加しようとしているとき、最初にグループが安全であるかどうかをチェックし、もしそうなら、ユーザーとパスワードを求めます。グループのセキュリティを取得するには数秒かかる場合があるため、プロセス全体に新しいスレッドが生成されます。グループにセキュリティが必要な場合に備えて、ダイアログをポップアップしたいと思います。バックグラウンドスレッドに関係している必要があると考えています。ダイアログをポップアップできない可能性があります...しかし、問題は、少し時間がかかるため、バックグラウンドスレッドのグループセキュリティを確認する必要があるということです。
グループが安全である場合にのみ、ユーザー/パスを尋ねるためのソリューションや任意の方法を考え出すことができることを願っています。これが背景スレッドです:
public void run() {
secInf = mGroupId.getSecurityInformation();
if (secInf.getAdmissionLevel() == CreateGroupDialog.PRIVATE_KEY_ACCESS) {
showUserPasswordDialog();
} else {
mService.joinGroup(mGroupId);
// Notifies handler to dismiss ProgresDialog and start activity
mHandler.sendMessage(Message.obtain(mHandler,
GroupsActivity.JOIN_SUCCESSFUL));
}
showuserpassworddialogが行う場所(マクイティはこのスレッドを生み出したアクティビティです):
private void showUserPasswordDialog() {
AlertDialog dialog;
// add this to your code
// This example shows how to add a custom layout to an AlertDialog
LayoutInflater factory = LayoutInflater.from(mActivity);
final View textEntryView = factory.inflate(
R.layout.alert_dialog_text_entry, null);
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setIcon(R.drawable.alert_dialog_icon);
builder.setTitle(R.string.ask_user_password);
builder.setView(textEntryView);
builder.setPositiveButton(R.string.ok_text,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String userName = ((EditText) mActivity
.findViewById(R.id.username_edit_alert_dialog))
.getText().toString();
String password = ((EditText) mActivity
.findViewById(R.id.password_edit_alert_dialog))
.getText().toString();
Credentials cred = new CredentialsL1(userName, password);
mSmeppService.joinGroup(mGroupId, cred);
mHandler.sendMessage(Message.obtain(mHandler,
GroupsActivity.JOIN_SUCCESSFUL));
});
builder.setNegativeButton(R.string.cancel_text,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
mHandler.sendMessage(Message.obtain(mHandler,
GroupsActivity.DISMISS_PROGRESS_DIALOG));
}
});
dialog = builder.create();
/* I found this somewhere, but didn't work either */
// Window window = dialog.getWindow();
// WindowManager.LayoutParams lp = window.getAttributes();
// lp.token = textEntryView.getWindowToken();
// lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
// window.setAttributes(lp);
// window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.show();
}
私はこの例外を取得しています:
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): FATAL EXCEPTION: Thread-38
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): android.view.InflateException: Binary XML file line #17: Error inflating class android.widget.EditText
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.createView(LayoutInflater.java:513)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at org.pfc.threads.GroupJoinerThread.showUserPasswordDialog(GroupJoinerThread.java:76)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at org.pfc.threads.GroupJoinerThread.run(GroupJoinerThread.java:52)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): Caused by: java.lang.reflect.InvocationTargetException
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.widget.EditText.<init>(EditText.java:51)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at java.lang.reflect.Constructor.constructNative(Native Method)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.createView(LayoutInflater.java:500)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): ... 8 more
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.os.Handler.<init>(Handler.java:121)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.MetaKeyKeyListener$MetaKeyDropbackHandler.<init>(MetaKeyKeyListener.java:605)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.MetaKeyKeyListener.<init>(MetaKeyKeyListener.java:96)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.BaseKeyListener.<init>(BaseKeyListener.java:25)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.TextKeyListener.<init>(TextKeyListener.java:66)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.TextKeyListener.getInstance(TextKeyListener.java:83)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.widget.TextView.<init>(TextView.java:806)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.widget.EditText.<init>(EditText.java:55)
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): ... 12 more
XMLレイアウトファイルは次のとおりです。
<EditText
android:id="@+id/username_edit_alert_dialog"
android:enabled="false"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:scrollHorizontally="true"
android:autoText="false"
android:capitalize="none"
android:gravity="fill_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium" />
<!-- Password -->
<TextView
android:id="@+id/password_view"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:text="@string/password_view_text"
android:gravity="left"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/password_edit_alert_dialog"
android:enabled="false"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:scrollHorizontally="true"
android:autoText="false"
android:capitalize="none"
android:gravity="fill_horizontal"
android:password="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
解決
バックグラウンドスレッドからUI操作を実行できないことは正しいです。それを行う方法は、を使用することです Handler
ダイアログをポップアップするためにすでに実装していること。だから:
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case GroupsActivity.DISMISS_PROGRESS_DIALOG:
//your existing dismiss code
break;
case GroupsActivity.CREATE_PROGRESS_DIALOG:
//create the dialog
break;
}
}
};
その後、実行方法は次のとおりです。
public void run() {
secInf = mGroupId.getSecurityInformation();
if (secInf.getAdmissionLevel() == CreateGroupDialog.PRIVATE_KEY_ACCESS) {
// do stuff
mHandler.sendMessage(Message.obtain(mHandler,
GroupsActivity.CREATE_PROGRESS_DIALOG));
// do more stuff
} else {
mService.joinGroup(mGroupId);
// Notifies handler to dismiss ProgresDialog and start activity
mHandler.sendMessage(Message.obtain(mHandler,
GroupsActivity.JOIN_SUCCESSFUL));
}
}
他のヒント
あなたは正しいです。バックグラウンドスレッドはダイアログをポップアップできません。必要なのはaです Handler
UIスレッドでダイアログをポップアップします。
それを行うのは良いアイデアではありませんが、この答えは完全性のためだけであり、ダイアログ形式の非UIスレッドを表示することが可能です。
handlerThread = HandlerThread("myHandlerThread")
handlerThread?.start()
handler1 = Handler(handlerThread?.looper)
handler1?.post {
AlertDialog
.Builder(this)
.setPositiveButton("ok") { dialogInterface: DialogInterface, i: Int -> dialogInterface.dismiss() }
.create()
.show()
}