【问题标题】:Android NetworkOnMainThreadException AsyncTaskAndroid NetworkOnMainThreadException AsyncTask
【发布时间】:2015-01-01 15:52:41
【问题描述】:

我在尝试通过 servlet 从 Android 将数据插入 MySQL 时遇到一些问题。所以我的情况是当地图在SingleTap时,它会得到坐标X和Y并插入到数据库中。

@Override
public void onCreate(Bundle savedInstanceState) {
    mMapView.setOnSingleTapListener(new OnSingleTapListener() {
        public void onSingleTap(float x, float y) {
            Point point = mMapView.toMapPoint(x, y);
                Log.e("Coord", point.toString());
                eventCtrl.createEvent(point.toString());
            }
    });
    new MyAsyncTask().execute();
}

private class MyAsyncTask extends AsyncTask<Void, Integer, Double> {
    @Override
    protected Double doInBackground(Void... params) {
        try {
            eventCtrl.retrieveEventJSON();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected void onPostExecute(Double result) {
    }

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

public void createEvent(String point) {
    HttpPost post = new HttpPost(ENeighbourhoodActivity.URL);

    HttpClient client = new DefaultHttpClient();

    List<NameValuePair> nvp = new ArrayList<NameValuePair>(2);
    nvp.add(new BasicNameValuePair("eventX", point));
    nvp.add(new BasicNameValuePair("eventY", point));

    try {
        post.setEntity(new UrlEncodedFormEntity(nvp));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    try {
        HttpResponse response = client.execute(post);
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

还有我的 servlet:

protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {

    PrintWriter out = response.getWriter();
    String eventX = request.getParameter("eventX");
    String eventY = request.getParameter("eventY");
    Connection con = null;
    Statement stmt = null;
    try {
        con = DriverManager.getConnection("jdbc:mysql://localhost/mydb",
                "root", "root");
    } catch (SQLException e) {
        e.printStackTrace();
    }

    try {
        stmt = con.createStatement();
    } catch (SQLException e) {
        e.printStackTrace();
    }

    String sqlStr = "INSERT into event VALUES (" + eventX + "," + eventY
            + ");";

    try {
        int rSet = stmt.executeUpdate(sqlStr);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

但是,我收到 NetworkOnMainThreadException 错误消息作为 LogCat:

11-05 20:37:29.690: E/Coord(26573): Point [m_attributes=[27289.373913043477, 34157.21304347826], m_description=com.esri.core.geometry.VertexDescription@7c5d0f85]
11-05 20:37:29.784: D/AndroidRuntime(26573): Shutting down VM
11-05 20:37:29.784: W/dalvikvm(26573): threadid=1: thread exiting with uncaught exception (group=0x40c3f1f8)
11-05 20:37:29.815: D/dalvikvm(26573): GC_CONCURRENT freed 498K, 13% free 10934K/12487K, paused 44ms+3ms
11-05 20:37:29.885: E/AndroidRuntime(26573): FATAL EXCEPTION: main
11-05 20:37:29.885: E/AndroidRuntime(26573): android.os.NetworkOnMainThreadException
11-05 20:37:29.885: E/AndroidRuntime(26573):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at libcore.io.IoBridge.connect(IoBridge.java:112)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at java.net.Socket.connect(Socket.java:842)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at Controller.EventController.createEvent(EventController.java:135)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at nyp.edu.eneighbourhood.ENeighbourhoodActivity$3.onSingleTap(ENeighbourhoodActivity.java:188)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at com.esri.android.map.MapOnTouchListener.onSingleTap(Unknown Source)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at com.esri.android.map.MapGestureDetector$a.onSingleTapConfirmed(Unknown Source)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:393)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at android.os.Looper.loop(Looper.java:137)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at android.app.ActivityThread.main(ActivityThread.java:4512)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at java.lang.reflect.Method.invokeNative(Native Method)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at java.lang.reflect.Method.invoke(Method.java:511)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:982)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
11-05 20:37:29.885: E/AndroidRuntime(26573):    at dalvik.system.NativeStart.main(Native Method)

我知道此错误消息是因为我试图访问网络内容,但我没有在后台进行。我想知道我有什么方法可以调用 MyAsyncTask 类中的 createEvent() 吗?

提前致谢。

【问题讨论】:

  • 让选民不高兴解释我做错了哪一部分?
  • 您的createEvent 正在调用网络操作。向我们展示您的代码。 (EventController.java:135)
  • @PedroOliveira 对不起,我忘了输入代码。现在更新了:)

标签: java android mysql servlets


【解决方案1】:

这个问题已经被问过无数次了......

您的创建事件createEvent 应该只在异步任务上调用,因为它执行网络操作。不要在您的活动中致电createEvent

【讨论】:

  • 但我必须从活动中获取一些价值并将它们传递给创建活动。如何在 doInBackground 中调用它?
  • 您是在告诉我们您不知道如何创建异步任务并将值传递给它?
【解决方案2】:

将您的观点作为参数传递给AsyncTask

@Override
public void onCreate(Bundle savedInstanceState) {
    mMapView.setOnSingleTapListener(new OnSingleTapListener() {
        public void onSingleTap(float x, float y) {
            Point point = mMapView.toMapPoint(x, y);
                Log.e("Coord", point.toString());
                new MyAsyncTask().execute(point);
            }
    });
}

private class MyAsyncTask extends AsyncTask<Point, Integer, Double> {
    @Override
    protected Double doInBackground(Point... params) {
        if(params.length == 1) {
            try {
                eventCtrl.createEvent(params[0].toString());
                eventCtrl.retrieveEventJSON();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    protected void onPostExecute(Double result) {
    }

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

【讨论】:

  • 但是现在让我们说点已更改为事件对象。所以我只是简单地将 Point... 参数替换为 Event... 参数?
  • 是的,还要将extends部分替换为AsyncTask&lt;Event, Integer, Double&gt;
  • 还有一个问题,params[0] 是干什么用的?抱歉,我对此很陌生。
  • execute 方法可以有多个参数,只要你需要。函数声明中的点... 代表了这一点。因此,当调用函数时,您会收到 params 数组,并且您可以像访问 Java 中的任何其他 array 一样访问它们。
  • 哦,我明白了。非常感谢!
猜你喜欢
  • 2012-11-16
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-13
相关资源
最近更新 更多