Android的AsyncTask的#2致命异常 [英] Android AsyncTask #2 Fatal Exception

查看:134
本文介绍了Android的AsyncTask的#2致命异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些问题,在Android中的AsyncTask#2致命的异常。所以,我所要做的是在地图上的一个水龙头,让X和Y坐标,并将其传递到AsyncTask的()类来执行的方法来获取地址。这里是$ C我的单水龙头$ CS和MyAsyncTask():

I am having some problem with AsyncTask #2 fatal exception in Android. So what I am trying to do is single tap on map, get the coordinates X and Y and pass them to AsyncTask() class to execute a method to get the address. Here is the codes of my single tap and MyAsyncTask():

mMapView.setOnSingleTapListener(new OnSingleTapListener() {
        public void onSingleTap(float x, float y) {
                eventModel.setEventX(String.valueOf(point.getX()));
                eventModel.setEventY(String.valueOf(point.getY()));
                new MyAsyncTask().execute(eventModel);
                CreateEvent.createEventDialog(context, point.getX(),
                        point.getY(), eventAddress);
                Log.i("Addr", eventAddress);
        }
    });
    new MyAsyncTask().execute();
}

public static class MyAsyncTask extends AsyncTask<Event, Integer, Double> {
    @Override
    protected Double doInBackground(Event... params) {
        try {
            eventAddress = eventCtrl.getStreetAddressFromGeometry(eventModel.getEventX(), eventModel.getEventY());
            eventCtrl.retrieveEventJSON();
            if (params.length == 1) {
                eventCtrl.createEvent(params[0]);
                // Refresh map after successfully added event
                eventCtrl.retrieveEventJSON();
                eventCtrl.plotEventOnMap(context);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(Double result) {   
    }

    protected void onProgressUpdate(Integer... progress) {
    }
}

和在EventController方法获取基于XY地址:

And the method in EventController to get the address based on XY:

public String getStreetAddressFromGeometry(String eventX, String eventY) {
    String streetName = "";
    try {
        URL url = new URL("http://www.onemap.sg/API/services.svc/revgeocode?token=qo/s2TnSUmfLz+32CvLC4RMVkzEFYjxqyti1KhByvEacEdMWBpCuSSQ+IFRT84QjGPBCuz/cBom8PfSm3GjEsGc8PkdEEOEr&location="+eventX+","+eventY+"");
        URLConnection conn = (URLConnection) url.openConnection();

        BufferedReader br = new BufferedReader(new InputStreamReader(
            (conn.getInputStream())));

        String responseString;

        while ((responseString = br.readLine()) != null) {
            try {
                JSONObject rawObj = new JSONObject(responseString);
                JSONArray searchResults = rawObj.getJSONArray("GeocodeInfo");
                for (int i = 0; i < searchResults.length(); i++) {
                    streetName = searchResults.getJSONObject(i).getString(
                            "BLOCK")
                            + " " + searchResults.getJSONObject(i).getString("ROAD") + " SINGAPORE";
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }   
    } catch (IOException e) {
        e.printStackTrace();
    }
    return streetName;
}

在我从单一的水龙头的地址,我将它传递给此方法:

After I get the address from single tap, I pass it to this method:

public static Event createEventDialog(final Context context,
        final double x, final double y, final String eventAddress) {
    AlertDialog.Builder AddDialog = new AlertDialog.Builder(context);
    AddDialog.setTitle("Add Event");

    LayoutInflater li = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View dialogView = li.inflate(R.layout.create_event, null);
    txtEventName = (EditText) dialogView.findViewById(R.id.txtEventName);
    txtEventDesc = (EditText) dialogView.findViewById(R.id.txtEventDesc);
    txtEventAddr = (EditText) dialogView.findViewById(R.id.txtEventAddr);

    txtEventAddr.setText(eventAddress);

    AddDialog.setView(dialogView);
    AddDialog.setPositiveButton("Ok",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    dialog.dismiss();
                }
            });

    AddDialog.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    dialog.dismiss();
                }
            });
    AddDialog.show();

    return addEventModel;
}

然而,与这些codeS,我打印出来,从单一的水龙头的地址,它显示的地址。但是,当我走出提示对话框,它应该显示的地址。然而,它没有显示任何东西,几秒钟后,应用程序关闭的错误消息:

However, with these codes, I printed out the address from single tap, it's showing the address. But when I prompt out the dialog box, it supposed to display the address. However, it is not showing anything and after a few seconds, the application shut down with the error message:

11-11 17:18:28.889: E/AndroidRuntime(4439): FATAL EXCEPTION: AsyncTask #2
11-11 17:18:28.889: E/AndroidRuntime(4439): java.lang.RuntimeException: An error occured while executing doInBackground()
11-11 17:18:28.889: E/AndroidRuntime(4439):     at android.os.AsyncTask$3.done(AsyncTask.java:278)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at java.lang.Thread.run(Thread.java:856)
11-11 17:18:28.889: E/AndroidRuntime(4439): Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x0
11-11 17:18:28.889: E/AndroidRuntime(4439):     at android.content.res.Resources.getValue(Resources.java:1019)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at android.content.res.Resources.getDrawable(Resources.java:663)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at Controller.EventController.plotEventOnMap(EventController.java:101)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at nyp.edu.eneighbourhood.ENeighbourhoodActivity$MyAsyncTask.doInBackground(ENeighbourhoodActivity.java:213)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at nyp.edu.eneighbourhood.ENeighbourhoodActivity$MyAsyncTask.doInBackground(ENeighbourhoodActivity.java:1)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
11-11 17:18:28.889: E/AndroidRuntime(4439):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-11 17:18:28.889: E/AndroidRuntime(4439):     ... 5 more
11-11 17:18:35.725: W/SurfaceView(4439): CHECK surface infomation creating=false formatChanged=false sizeChanged=false visible=false visibleChanged=true surfaceChanged=true realSizeChanged=false redrawNeeded=false left=false top=false
11-11 17:18:37.022: E/WindowManager(4439): Activity nyp.edu.eneighbourhood.ENeighbourhoodActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@4169d570 that was originally added here
11-11 17:18:37.022: E/WindowManager(4439): android.view.WindowLeaked: Activity nyp.edu.eneighbourhood.ENeighbourhoodActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@4169d570 that was originally added here
11-11 17:18:37.022: E/WindowManager(4439):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:428)
11-11 17:18:37.022: E/WindowManager(4439):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:267)
11-11 17:18:37.022: E/WindowManager(4439):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
11-11 17:18:37.022: E/WindowManager(4439):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
11-11 17:18:37.022: E/WindowManager(4439):  at android.view.Window$LocalWindowManager.addView(Window.java:537)
11-11 17:18:37.022: E/WindowManager(4439):  at android.app.Dialog.show(Dialog.java:278)
11-11 17:18:37.022: E/WindowManager(4439):  at android.app.AlertDialog$Builder.show(AlertDialog.java:932)
11-11 17:18:37.022: E/WindowManager(4439):  at nyp.edu.eneighbourhood.CreateEvent.createEventDialog(CreateEvent.java:124)
11-11 17:18:37.022: E/WindowManager(4439):  at nyp.edu.eneighbourhood.ENeighbourhoodActivity$3.onSingleTap(ENeighbourhoodActivity.java:192)
11-11 17:18:37.022: E/WindowManager(4439):  at com.esri.android.map.MapOnTouchListener.onSingleTap(Unknown Source)
11-11 17:18:37.022: E/WindowManager(4439):  at com.esri.android.map.MapGestureDetector$a.onSingleTapConfirmed(Unknown Source)
11-11 17:18:37.022: E/WindowManager(4439):  at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:393)
11-11 17:18:37.022: E/WindowManager(4439):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-11 17:18:37.022: E/WindowManager(4439):  at android.os.Looper.loop(Looper.java:137)
11-11 17:18:37.022: E/WindowManager(4439):  at android.app.ActivityThread.main(ActivityThread.java:4512)
11-11 17:18:37.022: E/WindowManager(4439):  at java.lang.reflect.Method.invokeNative(Native Method)
11-11 17:18:37.022: E/WindowManager(4439):  at java.lang.reflect.Method.invoke(Method.java:511)
11-11 17:18:37.022: E/WindowManager(4439):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:982)
11-11 17:18:37.022: E/WindowManager(4439):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
11-11 17:18:37.022: E/WindowManager(4439):  at dalvik.system.NativeStart.main(Native Method)
11-11 17:18:38.209: I/Process(4439): Sending signal. PID: 4439 SIG: 9

先谢谢了。

修改

AddDialog.setView(dialogView);
    AddDialog.setPositiveButton("Ok",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    addEventModel = new Event();
                    addEventModel = onConfirmAddEventClicked(context, x, y);
                    new MyAsyncTask().execute(addEventModel);
                    dialog.dismiss();
                }
            });

因此​​,这里是当用户选择从对话框好的一部分,它将得到用户输入,在这种情况下,它是在onConfirmEventClicked完成。然后,它会调用MyAsyncTask执行DB插入。

So here is the part when user select Okay from dialogue box, it will get the user inputs, in this case it was done in onConfirmEventClicked. Then it will call the MyAsyncTask to execute DB insertion.

推荐答案

呼叫 eventCtrl.plotEventOnMap(上下文); postExecute 来代替。这种方法似乎改变不能对 doInBackground

Call eventCtrl.plotEventOnMap(context); on postExecute instead. This method appears to change the UI which can't be done on doInBackground

修改

您必须调用 CreateEvent.createEventDialog 您的AsyncTask仅完成之后。对于我建议创建一个接口,并把它传递给你的任务。这将需要一些编码。让我们开始吧:

You will have to call CreateEvent.createEventDialog only after your AsyncTask finishes. For that I recomend creating an interface and pass it to your task. That will require some coding. Let's get started:

public static class MyAsyncTask extends AsyncTask<Event, Integer, Double> {
    public interface OnRoutineFinished{  //interface
        void onFinish();
    }
    private OnRoutineFinished mCallbacks;
    public MyAsyncTask(OnRoutineFinished callback){ //constructor with interface
        mCallbacks = callback;
    }

    public MyAsyncTask(){} //empty constructor to maintain compatibility

    @Override
    protected Double doInBackground(Event... params) {
        try {
            eventAddress = eventCtrl.getStreetAddressFromGeometry(eventModel.getEventX(), eventModel.getEventY());
            eventCtrl.retrieveEventJSON();
            if (params.length == 1) {
                eventCtrl.createEvent(params[0]);
                // Refresh map after successfully added event
                eventCtrl.retrieveEventJSON();
                eventCtrl.plotEventOnMap(context);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(Double result) {
        if(mCallbacks !=null)
            mCallbacks.onFinish(); //call interface on finish
    }

    protected void onProgressUpdate(Integer... progress) {
    }
}

接下来当你创建asyntask传递事件中,你要打电话的时候异步完成:

Next when you create your asyntask pass the event you want to call when the async finishes:

    new MyAsyncTask(new MyAsyncTask.OnRoutineFinished() {
        @Override
        public void onFinish() {
             CreateEvent.createEventDialog(context, point.getX(),
                    point.getY(), eventAddress);  //this will be called after the task finishes
        }
    }).execute(eventModel);

这篇关于Android的AsyncTask的#2致命异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆