草庐IT

android - 从非 UI 线程弹出对话框

coder 2023-12-10 原文

我正在开发一个面向群体的网络应用程序。问题是,当我要加入一个群组时,它首先会检查该群组是否安全,如果安全,它会询问用户名和密码。获得组安全可能需要几秒钟,所以我为整个过程生成了一个新线程。我想弹出一个对话框,以防该组需要安全性。我认为这可能与后台线程有关,它们可能无法弹出对话框...但问题是我需要在后台线程中检查组安全性,因为这需要一点时间。

希望任何人都可以提出解决方案或仅在组安全时才询问用户/密码的任何方式。这是后台线程:

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 的作用(mActivity 是生成此线程的 Activity ):

 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));
    }
}

关于android - 从非 UI 线程弹出对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4432453/

有关android - 从非 UI 线程弹出对话框的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  3. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  4. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  5. ruby - 如何让Ruby捕获线程中的语法错误 - 2

    我正在尝试使用ruby​​编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?

  6. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  7. ruby - 如何在 ruby​​ 中运行后台线程? - 2

    我是ruby​​的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp

  8. ruby - Rails 开发服务器、PDFKit 和多线程 - 2

    我有一个使用PDFKit呈现网页的pdf版本的Rails应用程序。我使用Thin作为开发服务器。问题是当我处于开发模式时。当我使用“bundleexecrailss”启动我的服务器并尝试呈现任何PDF时,整个过程会陷入僵局,因为当您呈现PDF时,会向服务器请求一些额外的资源,如图像和css,看起来只有一个线程.如何配置Rails开发服务器以运行多个工作线程?非常感谢。 最佳答案 我找到的最简单的解决方案是unicorn.geminstallunicorn创建一个unicorn.conf:worker_processes3然后使用它:

  9. ruby - Ruby 1.9.1 中的 native 线程,对我有什么好处? - 2

    所以,Ruby1.9.1现在是declaredstable.Rails应该与它一起工作,并且正在慢慢地将gem移植到它。它具有native线程和全局解释器锁(GIL)。自从GIL到位后,原生线程是否比1.9.1中的绿色线程有任何优势? 最佳答案 1.9中的线程是原生的,但它们被“放慢了速度”,一次只允许一个线程运行。这是因为如果线程真的并行运行,它会混淆现有代码。优点:IO现在在线程中是异步的。如果一个线程阻塞在IO上,那么另一个线程将继续执行直到IO完成。C扩展可以使用真正的线程。缺点:任何非线程安全的C扩展都可能存在使用Thre

  10. ruby - 使写入文件线程安全 - 2

    我在一个ruby​​文件中有一个函数可以像这样写入一个文件File.open("myfile",'a'){|f|f.puts("#{sometext}")}这个函数在不同的线程中被调用,使得像上面这样的文件写入不是线程安全的。有谁知道如何以最简单的方式使这个文件写入线程安全?更多信息:如果重要的话,我正在使用rspec框架。 最佳答案 您可以通过File#flock给锁File.open("myfile",'a'){|f|f.flock(File::LOCK_EX)f.puts("#{sometext}")}

随机推荐