【问题标题】:Android startactivity freezes the appAndroid startactivity 冻结应用
【发布时间】:2017-06-17 21:50:45
【问题描述】:

我制作了非常简单的应用程序。基本上,如果按下按钮,我有活动 A 会启动活动 B。这是代码

openMapFAB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(), MapActivity.class);
                intent.putExtra("routeId", id);
                startActivity(intent);
            }
        });

但这就是问题所在。活动B非常繁重(它基本上是打开地图(mapsforge)并进行其他繁重的计算)。因此,当按下按钮时,我的 UI 冻结了大约 4 秒,然后我打开了活动 B。我想展示一些动画,比如圆形进度条或类似的东西。那么是否可以不在 UI 线程中启动活动?

这是我目前尝试过的

 new Thread(new Runnable() {
                    @Override
                    public void run() {
                        while (progressStatus < 100) {
                            progressStatus += 25;
                            handler.post(new Runnable() {
                                @Override
                                public void run() {
                                    //animation code
                                }
                            });

                            try {
                                Thread.sleep(1600);
                                if (progressStatus == 100){
                                    Intent intent = new Intent(getActivity(), MapActivity.class);
                                    intent.putExtra("routeId", id);
                                    startActivity(intent);
                                }

                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();

但这并不是我所需要的。有什么解决方案或建议吗?

【问题讨论】:

  • 如果繁重的代码在 MapActivity 中,这将不起作用。您应该尝试重构 MapActivity 以将代码移动到例如线程或异步任务。如果您需要帮助,请添加 MapActivity 的代码

标签: android android-activity ui-thread


【解决方案1】:

1) 那么是否可以不在 UI 线程中启动活动

应仅在主 UI 线程中处理活动。您将无法在其他线程中启动活动。即使在后台线程中处理数据后,也可以使用runOnUiThread 之类的活动方法来调用或推送活动

如果你在主线程中执行长操作,Android会抛出ANR

2) 然而,这并不是我所需要的。任何解决方案或 建议?

现在另一种方法是使用AsyncTaskIntentService 在后台对您的活动进行繁重的操作,并显示进度条,直到这些操作完成。

此操作完成后,将数据发布到您的 MapActivity。

1) Sample Intent Service implementation

2) Sample AsyncTask example

onCreate 上的 AsyncTask 示例如下

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new BackAsync().execute("URL");
}
private String getURLDetailsTitle(String url) {
  //Retrieve data from external URL
}
//AsyncTask to fetch data from URL called inside onCreate
private class BackAsyncextends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... urls) {
        String str = getURLDetailsTitle(urls[0]);
        while(true) {
           publishProgress(str);

        }
        return str;
    }

    @Override
    protected void onProgressUpdate(String... progress) {
        //update progress
    }

    protected void onPostExecute(Long result) {
         //update UI changes
     }

【讨论】:

    【解决方案2】:

    使用 AsyncTask 并在 doInBackground 方法中启动进度条并在 onPostExecute 方法中关闭它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      • 2011-05-23
      • 1970-01-01
      • 2021-09-24
      • 2017-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多