即使使用AsyncTask,也会出现NetworkOnMainThreadException

时间:2015-03-06 12:43:26

标签: android android-asynctask

我在尝试在我正在制作的应用中实施网络处理时遇到了这个问题。我环顾四周,找不到任何我认为真的适用于我的情况。我创建了一个静态类,我处理所有网络,所以我可以直接调用类中的方法,而无需创建实例。这是给我错误的代码。字符串变量"输入"是类中的静态字段。

private static void getJsonInput(final String url){
    new AsyncTask<String, Void, String>() {
        @Override
        protected String doInBackground(String... params) {
            String tempInput = "";
            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(url);
            try {
                HttpResponse response = client.execute(get);
                HttpEntity entity = response.getEntity();
                tempInput = EntityUtils.toString(entity);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return tempInput;
        }
        @Override
        protected void onPostExecute(String tempInput) {
            super.onPostExecute(tempInput);
            input = tempInput;
        }
    };
}

这是我使用网络处理的应用程序的唯一部分。有谁知道为什么会发生这种情况?

我在同一个类中使用此方法调用该方法:

public static ArrayList<String> getOptions(String url){
    ArrayList<String> options = new ArrayList<>();
    getJsonInput(url);
    try {
        JSONObject jsonObject = new JSONObject(input);
        JSONArray jsonArray = jsonObject.getJSONArray("grupper");
        for (int i = 0; i < jsonArray.length(); i++) {
            options.add(jsonArray.getString(i));
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return options;
}

这是我的堆栈跟踪:

03-06 11:12:11.005    1986-1986/com.example.daniel.androidlab3 E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.daniel.androidlab3, PID: 1986
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.daniel.androidlab3/com.example.daniel.androidlab3.MainActivity}: android.os.NetworkOnMainThreadException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: android.os.NetworkOnMainThreadException
            at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
            at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
            at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
            at java.net.InetAddress.getAllByName(InetAddress.java:215)
            at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
            at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
            at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
            at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
            at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
            at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
            at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
            at com.example.daniel.androidlab3.NetworkHandling.getJsonInput(NetworkHandling.java:41)
            at com.example.daniel.androidlab3.NetworkHandling.getOptions(NetworkHandling.java:23)
            at com.example.daniel.androidlab3.MainFragment.onCreateView(MainFragment.java:36)
            at android.app.Fragment.performCreateView(Fragment.java:2053)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
            at android.app.BackStackRecord.run(BackStackRecord.java:833)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
            at android.app.Activity.performStart(Activity.java:5948)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

这是我在MainFragment中调用以下方法的行:

    ArrayList<String> options = NetworkHandling.getOptions("http://tddd80-afteach.rhcloud.com/api/groups");

1 个答案:

答案 0 :(得分:0)

我终于明白了。显然,当一个变量在一个方法的主线程中给出一个值时,在我的情况NetworkHandling.getOptions()中使用的方法是否使用AsyncTask临时打开一个新线程并不重要。它仍然会将此视为在主线程中使用网络。

我通过从NetworkHandling类中删除AsyncTask并将其替换为执行网络连接的常规方法来解决它。然后在片段中,我创建了一个方法,在其中我放置了一个调用网络处理方法的AsyncTask,如下所示:

private ArrayList<String> options;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ListView listView = new ListView(getActivity());
    options = new ArrayList<>();
    getOptions();
    adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, options);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(this);
    return listView;
}

private void getOptions(){
    new AsyncTask<Void,Void,ArrayList<String>>(){
        @Override
        protected ArrayList<String> doInBackground(Void... params) {
            String input = NetworkHandling.getJsonInput("http://tddd80-afteach.rhcloud.com/api/groups");
            return JsonParser.getGroups(input);
        }

        @Override
        protected void onPostExecute(ArrayList<String> groups) {
            options.addAll(groups);
            adapter.notifyDataSetChanged();
        }
    }.execute();
}