如何从后台进程访问对话框?

时间:2015-10-21 04:02:51

标签: android android-layout android-fragments android-dialogfragment android-dialog

我有一个带有自定义适配器的ListView,它显示了我周围的wif列表。单击一个项目时,我会显示一个包含详细信息的对话框。该对话框是从DialogFragment派生的自定义类,在Wifi扫描完成后使用此代码显示:

private class WifiScanReceiver extends BroadcastReceiver {
        public void onReceive(Context c, Intent intent) {
            List<ScanResult> wifiScanList = wifi.getScanResults();
            Log.i("WifiAnal", "rec");

            lv.setAdapter(new WifiListAdapter(getApplicationContext(), R.layout.itemlistrow, wifiScanList));
            lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    ScanResult listItem = (ScanResult)lv.getItemAtPosition(position);
                    WifiDetailsDialogFragment d = new WifiDetailsDialogFragment();

                    // Supply num input as an argument.
                    Bundle args = new Bundle();
                    args.putString("ssid", listItem.SSID);

                    d.setArguments(args);

                    d.show(getSupportFragmentManager(), "fir");

                    // TODO: PUT ASYNC CALL HERE AND PROCESS FETCHED DATA.
                    // TODO: SHOW ASYNC RESULT ON OPEN DIALOG

                }

            });

            mSwipeRefreshLayout.setRefreshing(false);
        }
    }

我的WifiDetailsDialogFragment课程负责充气xml布局并使用确定按钮在应用程序顶部正确显示。

现在假设我显示了对话框,现在我想运行后台任务(比如从外部服务器上的DB中获取更多详细信息),在完成后,如果对话框仍处于打开状态,则将结果放入其布局中(可能是操作)一些已存在和膨胀的TextViews的值)。如果它在那时关闭,什么也不做。

如何从onItemClick启动的后台运行的进程中访问我的布局小部件?我尝试了d.getView(),但这会返回null。通过FragmentManager以某种方式正确的方式?我不想绘制新的对话框,而是编辑现有的成员。

谢谢!

2 个答案:

答案 0 :(得分:0)

好吧,如果您只是想访问您的片段,可以使用

getSupportFragmentManager().findFragmentByTag("fir")

此标记必须在您的片段交易时定义(在您的情况下为show(),因为它是DialogFragment

但我应该建议你上面定义的代码看起来有点奇怪。您如何期望在那里获得异步调用的结果?如果您继续使用此类代码,则会获得android.os.NetworkOnMainThreadException

为避免这种情况,您应该在AsyncTask方法上构建onPostExecute并操纵您的用户界面,然后您将返回主循环。

答案 1 :(得分:-1)

我建议您使用Otto将后台线程中的事件发送到UI逻辑。这些事件可能包含您需要的任何信息。您必须遵循的步骤是:

  • 在后台线程和对话框片段中注入您的总线(可能会根据您的依赖管理器解决方案而有所不同)
  • register()您的片段到公交车
  • 创建一个接收事件的方法,并使用@Subscribe
  • 对其进行注释
  • post()来自后台线程的事件(要做到这一点,你必须到达主循环器,但这可以通过修改otto总线轻松完成,如下面的代码)

    public class MainThreadBus extends Bus {
     private final Handler handler = new Handler(Looper.getMainLooper());
    
     @Override public void post(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            super.post(event);
        } else {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    MainThreadBus.super.post(event);
                }
            });
        }
    }
    

此答案中提供了此代码:How to send event from Service to Activity with Otto event bus?

以这种方式编写解决方案实际上会更安全,因为您可以在unregister()方法上onPause片段,因此您无需检查片段是否仍附加到活动时操纵它的UI。