0

我有一个 xml 解析器,它解析一个带有 1056 个我在本地获取的信息标签的大文件(不是基于 url)。

我想在这个东西通过for循环运行时显示一个对话框,但我只是看到一个白屏,直到所有加载完成。我试过在几个不同的地方添加一个 dialog.show() ,甚至在 onCreate 没有任何成功。我在这里想念什么?我曾尝试在 Handler 和 Async 中运行此方法,但每次都会出现 Not On Main Thread 错误...您如何在主线程上运行带有对话框的长任务?

在我的 onCreate 中,我只是这样做(以及其他正常的布局、操作栏等......):

buildMap();

这是我的方法:

public void buildMap() {
        try {

            File fXmlFile = new File(
                    "/storage/emulated/0/snoteldata/kml/snotelwithlabels.kml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);

            doc.getDocumentElement().normalize();

            NodeList nList = doc.getElementsByTagName("Placemark");
            int temp;
            for (temp = 0; temp < nList.getLength(); temp++) {

                Node nNode = nList.item(temp);

                if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                    Element eElement = (Element) nNode;

                    String name = eElement.getElementsByTagName("name").item(0)
                            .getTextContent();

                    Spanned desc = Html.fromHtml(eElement
                            .getElementsByTagName("description").item(0)
                            .getTextContent());

                    String lon = eElement.getElementsByTagName("longitude")
                            .item(0).getTextContent();

                    String lat = eElement.getElementsByTagName("latitude")
                            .item(0).getTextContent();

                    lon = lon.trim();
                    lat = lat.trim();

                    double lati = Double.parseDouble(lat);
                    double lngi = Double.parseDouble(lon);

                    LatLng LOCATION = new LatLng(lati, lngi);

                    map.addMarker(new MarkerOptions()
                            .position(LOCATION)
                            .title(name)
                            .snippet(desc.toString())
                            .icon(BitmapDescriptorFactory
                                    .fromResource(R.drawable.wfmi_icon48)));
                    map.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
                        @Override
                        public void onInfoWindowClick(Marker arg0) {
                            msg(arg0.getSnippet());
                        }
                    });
                }

            }

            showLocation();

        } catch (Exception e) {
            Log.e("SnoTelData Buildmap Error", e.getMessage());
        }
    }

如何显示这个 for 循环正在运行并等待一秒钟?

编辑::::

感谢您的回复。我已经尝试过没有成功的建议。我收到 Not on Main Thread 错误。

这是我的异步任务:

private class BuildTask extends AsyncTask<String, Void, Void> {
        @Override
        protected Void doInBackground(String... params) {
            buildMap();
            return null;
        }

        protected void onPreExecute() {
            dialog.show();
         }

         protected void onPostExecute(Void result) {
            dialog.cancel();
         }
    }

我从 onCreate 调用 if:

new BuildTask().execute();

为什么我仍然得到不在主线程上的错误?我正在从 onCreate 执行此操作。

4

4 回答 4

0

使用 AsyncTask 并在 onPreExecute() 中显示您的对话,并在 onPostExecute() 中显示您的dismissDialog()

于 2013-09-12T06:20:44.427 回答
0

使用 AsyncTask。在doInBackground()方法buildMap()中。在onPreExecute()andonPostExecute()方法中显示和隐藏对话框。

     protected void onPreExecute() {
        //Show Dialog
     }

     protected void onPostExecute(Void result) {
         //Dismiss Dialog
     }
于 2013-09-12T06:18:17.953 回答
0

使用一个Thread,可能是一个AsyncTaskbuildMap()并在线程中运行该方法。ProgressDialog在调用该方法之前创建一个并ProgressDialog在 UI 线程上显示它。dismiss当你所有的解析完成后,只是ProgressDialog(在 UI 线程上)。

于 2013-09-12T06:19:50.833 回答
0

您必须在单独的线程中在后台进行解析。然后,该线程将更新消息发送到显示进度的主线程。

我创建了一个处理所有这些的 ProgressDialog 类

public class ProgressDialogForParser extends
    DialogFragment {

它有一个名为:的静态处理程序theHandlerForScreenUpdate

public static Handler theHandlerForScreenUpdate;

这是如何初始化它:

public final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
    updateProgressDialog(msg); // here you do whatever you like to update the screen
}
};

这是一种静态方法,您可以从解析器线程轻松使用它来更新屏幕进度。此外,我将一些信息传递给处理程序,因此它知道它应该做什么,以防你也需要它。

   static public void sendMessageToProgressDialog(
        int msgID, String msgText, boolean statusBool) {
    if (theHandlerForScreenUpdate == null)
        return;
    Message msgForProgressDialogDuringConnectionTest = theHandlerForScreenUpdate
        .obtainMessage(msgID);
    Bundle bundle = new Bundle();
    bundle.putBoolean(msgText, statusBool);
    msgForProgressDialogDuringConnectionTest.setData(bundle);
    theHandlerForScreenUpdate
        .sendMessage(msgForProgressDialogDuringConnectionTest);

    }
于 2013-09-12T06:28:01.903 回答