Java 主线程上的Android网络使用
所以,我一直在为一个客户端创建和应用程序,并进入了网络部分。我目前正在从清单中删除targetSDK标记,因此不会得到MainThreadException。我看过一些人和文档,他们说我不应该在非主线程上进行网络操作,因为它比较慢 问题是:如果不在主线程上进行网络操作,我在哪里以及如何进行网络操作? 代码如下:Java 主线程上的Android网络使用,java,android,multithreading,http,Java,Android,Multithreading,Http,所以,我一直在为一个客户端创建和应用程序,并进入了网络部分。我目前正在从清单中删除targetSDK标记,因此不会得到MainThreadException。我看过一些人和文档,他们说我不应该在非主线程上进行网络操作,因为它比较慢 问题是:如果不在主线程上进行网络操作,我在哪里以及如何进行网络操作? 代码如下: public static class MagFragment extends Fragment { public static final String ARG_MAGAZ
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;
}
}
你应该利用这个班。它不在主线程上运行,但您可以从主线程调用它。您可以让活动等待,直到任务准备就绪。同时,您可以在屏幕上显示进度条。简单的方法,我已经做了类似的事情,您可以实现一个线程类
您拥有该对象,并向其传递希望它拥有的变量,然后启动线程。似乎你所要做的就是设置某个东西的文本,这样你就可以将它传递给它需要设置文本的对象,而它似乎没有太多内容。只需将http请求内容移动到thread类的运行中。一旦你启动一个线程,就不能保证计时,它可能会晚一点完成,但如果你只是想更新一个textview,那可能就足够了。为什么要这样做?使用异步任务发送请求。你想在完成后通知你的班级吗?使用回调侦听器。这很容易 以下是我的示例(未测试)
public void doNetworkStuff(){
新建doAsyncNetworkStuff().execute(此);
}
@凌驾
已完成的公用void onTaskCompleted(字符串str){
}
私有类请求扩展了异步任务{
私有HttpInterface HttpInterface;
公共请求(HttpInterface HttpInterface){
this.httpInterface=httpInterface;
}
@凌驾
受保护的void onPreExecute(){
//做你的初始化等等
}
@凌驾
受保护的Void doInBackground(对象…参数){
//做你的背景网络工作
httpInterface.onTaskCompleted(str);
返回null;
}
}
这是HttpInterface
公共接口HttpInterface{
void onTaskCompleted(字符串str);
}
它是如何工作的?您正在调用一个Asynctask,该任务使用回调侦听器完成网络工作。完成此操作后,将调用带有onTaskCompleted的Callbacklistener。这意味着您的Mainclass将收到缓冲区或其他通知。你可以处理你所有的东西之后,没有阻塞。享受。不,不,不,不要自己实现这个,除非你这样做是为了学习线程和异步任务。我建议您使用一个现有的库,该库构建在Android类之上,并抽象掉所有乏味和容易出错的代码,而不是重新发明轮子,花费大量时间进行调试,并试图找出如何处理重试、线程池、cookie等等
您应该使用类似的东西,它是“一个基于异步回调的Android Http客户端,构建在Apache的HttpClient库之上。所有请求都是在应用程序的主UI线程之外发出的,但是任何回调逻辑都将在使用安卓处理程序消息传递创建回调的同一线程上执行。”你读过这篇文章吗?如果你正在做下一件大事:考虑一下:我已经做了一些事情,我只是创建一个线程类,创建一个对象,传递它需要的变量,并调用它的开始。关于线程的更多信息我已经了解了网络基本操作,还有一个问题。。。因为它在Fragmemt中,所以我必须将getActivity()放在行'ConnectivityManager connMgr=(ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);'这使得“new DownloadWebpageTask().execute(stringUrl);”出现错误“无法访问MainActivity类型的封闭实例”。@DrDebug如果示例应用程序/将其集成到您自己的应用程序中仍然存在问题,请重写该问题以反映所做的更改(或编写一个新的),并准确指定失败的原因。
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;
}
}