0

所以,我一直在为客户创建和应用程序并进入网络部分。我目前正在从清单中删除 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

4 回答 4

1

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

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

于 2013-05-22T21:34:16.680 回答
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 将收到有关缓冲区或其他内容的通知。之后您可以处理所有内容而不会阻塞。享受。

于 2013-05-22T21:33:30.767 回答
0

您应该使用AsyncTask类。它不在主线程上运行,但您可以从主线程调用它。你可以让你的活动等到你的异步任务准备好。同时,您可以在屏幕上显示进度条。

于 2013-05-22T21:15:13.160 回答
0

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

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

于 2013-05-22T21:17:33.853 回答