主线程上的Android网络使用情况

时间:2013-05-22 20:56:06

标签: java android multithreading http

所以,我一直在创建和应用客户端并进入网络部分。我目前正从清单中删除targetSDK标记,所以我没有得到MainThreadException。我见过人们和文档说我不应该在主线程上进行网络操作,因为它更慢......

问题:如果不在主线程上进行网络操作,我在哪里以及如何进行网络操作? 这是代码:

  public static class MagFragment extends Fragment {
    public static final String ARG_MAGAZINE_NUMBER = "magazine_number";

    public MagFragment() {
        // Empty constructor required for fragment subclasses
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        int i = getArguments().getInt(ARG_MAGAZINE_NUMBER);
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        if(i != 0){
            rootView = inflater.inflate(R.layout.fragment_magazine, container, false);
            TextView magText = (TextView) rootView.findViewById(R.id.textViewMag);

            try {
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost("http://csddata.site11.com");
                HttpResponse response = httpclient.execute(httppost);

                HttpEntity httpEntity = response.getEntity();
                InputStream inputstream = httpEntity.getContent();
                try{

                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputstream,"iso-8859-1"),8);
                    magText.setText(reader.readLine());

                }catch (Exception e){
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }


            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
        }

        String magazine = getResources().getStringArray(R.array.magazine_array)[i];
        Log.d("MagFragment", "MagNumber" + i);

        getActivity().setTitle(magazine);
        return rootView;
    }
}

4 个答案:

答案 0 :(得分:1)

不,不,不,不要自己实现,除非你这样做是为了了解线程和异步任务。而不是重新发明轮子和花费时间进行调试并试图弄清楚如何处理重试,线程池,cookie以及我不建议您使用基于Android类构建的现有库并抽象出所有繁琐的和容易出错的代码。

你应该使用类似Android Async Http Client的东西,它是“基于异步回调的Android Http客户端,建立在Apache的HttpClient库之上。所有请求都是在应用程序的主UI线程之外发出的,但是任何回调逻辑将在使用Android的Handler消息传递创建回调的同一线程上执行。“

答案 1 :(得分:0)

您应该使用班级AsyncTask。它不在主线程上运行,但您可以从主线程调用它。你可以让你的活动等到你的asynctask准备好了。在此期间,您可以在屏幕上显示进度条。

答案 2 :(得分:0)

简单的方法,我已经完成了这样的事情,你可以实现一个线程类,http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

你有对象并将它想要的变量传递给它,然后启动线程。似乎所有你想要做的就是设置一些东西的文本,这样你就可以传递它需要设置文本的那个对象,而且似乎没有更多的东西。只需将您的http请求移动到线程类的运行。一旦你开始一个线程就不能保证计时,它可以稍晚完成,但是如果你只想更新一个可能足够的文本视图。

答案 3 :(得分:0)

你为什么要这样做?使用AsyncTask发送请求。你想在课程结束后通知你的课程吗?使用回调监听器。这很容易。

这是我的例子(未经测试)

public void doNetworkStuff() {
    new doAsyncNetworkStuff().execute(this);
}

@Override
 public void onTaskCompleted(String str) {
}


private class doSingleRequest extends AsyncTask<Object, Void, Void> {

private HttpInterface httpInterface;

public doSingleRequest(HttpInterface httpInterface) {
    this.httpInterface = httpInterface;
}

@Override
protected void onPreExecute() {
 //do your inits and so on
}

@Override
protected Void doInBackground(Object... params) {
   //do your background network stuff
        httpInterface.onTaskCompleted(str);

    return null;
}
}

这是HttpInterface       公共接口HttpInterface {     void onTaskCompleted(String str);     }

它是如何工作的?您正在调用Asynctask,它使用回调侦听器来处理您的网络内容。完成此操作后,将调用带有onTaskCompleted的Callbacklistener。这意味着您的Mainclass将通过缓冲区或其他任何方式得到通知。您可以在此之后处理所有内容而不会阻止。享受。