为什么我一直收到NetworkOnMainThreadException?

时间:2014-09-16 20:19:19

标签: java android exception

我已经通过所有SO的解决方案来解决NetworkOnMainThreadException包括ASync类 - 但仍然有问题

这是我的简单代码:

ActivityMain 类:

public class MainActivity extends Activity
{
    ArrayList<City> alCities = new ArrayList<City>();
    Activity activity=null;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        activity=this;

        new MyTask(activity, alCities).execute(); //<--- running ASYNC here
    }
}

MyTask 类:

public class MyTask extends AsyncTask<Void, Void, ArrayList<City>>
{
    ArrayList<City> alCities = null;
    Activity ac = null;

    public MyTask(Activity activity, ArrayList<City> al) //ctor
    {
        alCities = al;
        this.activity= activity;
    }

    @Override
    protected ArrayList<City> doInBackground(Void... params)
    {
        try
        {
            Object myJsonObject = Util.getJson("http://jsbin.com/lobel/2.js"); //internet job

                try
                {
                    //...fill array list...
                    return alCities;

                } catch (Exception e)
                {
                    ...
                }
            }
        } catch (Exception e)
        {
            ...
        }
        return null;
    }


    protected void onPostExecute(ArrayList<City> alCities)
    {
    ...
    //update UI
    ListView l1 = (ListView) ac.findViewById(R.id.list_view_1);
    ///
    }

}

但仍然:

enter image description here

nb:

如果我把:

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
} 

确实有效:

enter image description here

问题

我做错了什么?

完整堆栈跟踪http://jsbin.com/bilafi/2/edit

我只是加载json文件!

onPostExecute 的完整代码:

protected void onPostExecute(ArrayList<City> alCities)
    {
        CustomArrayAdapter adapter = new CustomArrayAdapter(ac, alCities);

        ListView l1 = (ListView) ac.findViewById(R.id.list_view_1);
        l1.setAdapter(adapter);
        l1.setOnItemClickListener(new OnItemClickListener()
        {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id)
            {
                // Util.Toast(getBaseContext(), "You have selected " + 1);

            }
        });
    }

2 个答案:

答案 0 :(得分:7)

这是你崩溃的地方:

at com.example.listview3.Util.getBitmapFromURL(Util.java:179)
at com.example.listview3.CustomArrayAdapter.getView(CustomArrayAdapter.java:67)

您已正确使用AsyncTask。但是,在填写列表时,您尝试使用网络获取图像,再次。这一次,您没有使用AsyncTask,因此NetworkOnMainThreadException

答案 1 :(得分:3)

从完整堆栈跟踪中可以清楚地看到错误源

om.example.listview3.CustomArrayAdapter.getView()正在尝试从网址

加载Bitmap

即。at com.example.listview3.Util.getBitmapFromURL(Util.java:179)

onPostExecute在主UI线程中运行,这就是您获得NetworkOnMainThreadException

的原因

您可能需要考虑使用volley,它可以在okhttp之上工作并提供易于使用的方法来加载图像而不会出现线程麻烦,它已在Google IO 2013中引入