Java 独立线程上的网络相关任务
我目前有一个spoly类,这是我编写的一个类,它使用JSoup库解析HTML。这里还显示了我的Java 独立线程上的网络相关任务,java,android,multithreading,Java,Android,Multithreading,我目前有一个spoly类,这是我编写的一个类,它使用JSoup库解析HTML。这里还显示了我的占位符片段类 public static class PlaceholderFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInst
占位符片段
类
public static class PlaceholderFragment extends Fragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
final Button button = (Button) rootView.findViewById(R.id.button1);
final TextView textview = (TextView) rootView.findViewById(R.id.textview1);
button.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Pollen pollenObject = new Pollen(19104);
textview.setText(pollenObject.getCity());
}
});
return rootView;
}
}
这是我的花粉课
public static class Pollen
{
@SuppressLint("SimpleDateFormat")
public Pollen(int zipcode)
{
this.zipcode = zipcode;
Document doc;
try
{
// pass address to
doc = Jsoup.connect("http://www.wunderground.com/DisplayPollen.asp?Zipcode=" + this.zipcode).get();
// get "location" from XML
Element location = doc.select("div.columns").first();
this.location = location.text();
// get "pollen type" from XML
Element pollenType = doc.select("div.panel h3").first();
this.pollenType = pollenType.text();
SimpleDateFormat format = new SimpleDateFormat("EEE MMMM dd, yyyy");
// add the four items of pollen and dates
// to its respective list
for(int i = 0; i < 4; i++)
{
Element dates = doc.select("td.text-center.even-four").get(i);
Element levels = doc.select("td.levels").get(i);
try
{
pollenMap.put(format.parse(dates.text()), levels.text());
}
catch (ParseException e)
{
e.printStackTrace();
}
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这是一个异步任务
。您必须使用AsyncTask
执行所有网络操作。
它基本上有3种方法
onPreExecute()
doInBackground()
onPostExecute()
doInBackground()
方法中执行网络操作。更新onPostExecute()中的UI
AsyncTask
是Android框架提供的一种机制,用于在不阻塞主UI线程的情况下促进长时间运行任务的执行。阅读Android开发者网站上的教程,了解关于这个主题的详细介绍
提供的链接应该可以帮助您使用AsyncTask
机制重新设计类
希望这有帮助是的,您试图在UI线程内进行非法联网,并捕获异常,该异常是
NetworkOnMainThreadException
您可以使用现在正在执行的AsyncTask
,而不是在主线程内连接,但它不应该是抽象的,它只是一个普通类,因此您可以执行AsyncTask
示例:
public class RetrievePollenTask extends AsyncTask<Integer, Void, Pollen>
{
protected Pollen doInBackground(String... params)
{
Pollen pollenObject = new Pollen(19104);
return pollenObject;
}
protected void onPostExecute(Pollen result) {
textview.setText(pollenObject.getCity());
}
}
公共类RetrievePollenTask扩展异步任务
{
受保护花粉背景(字符串…参数)
{
花粉对象=新花粉(19104);
返回pollenObject;
}
受保护的void onPostExecute(结果){
setText(pollenObject.getCity());
}
}
可以将asynctask作为片段的内部类,这样就不需要在其上传递上下文参数。也不要将更新任何视图放在
doInBackground
中,因为它将捕获异常的线程不同。一个AsyncTask
用于在非UI线程中运行代码,但也有可以与UI交互的方法
AsyncTask
这定义了AsyncTask使用的对象。如果不使用任何对象,请使用
Void
- 第一个是
的输入doInBackground()
- 第二个参数是
的参数,用于定期更新用户的进度onProgressUpdate()
- 最后一个是从
doInBackground()返回的结果
对象声明的。。。vars
实际上是可以使用vars[index]
访问的数组。如果只传递一个变量,请使用var[0]
类检索PollenTask扩展异步任务
{
@凌驾
受保护的void onPreExecute(){
//在*任务运行之前*在此处设置ProgressBar或其他UI操作
}
@凌驾
受保护花粉背景(字符串…参数)
{
//在此处执行单独的非UI线程操作
//调用publishProgress(int)定期更新UI
返回pollenObject;
}
@凌驾
受保护的void onProgesUpdate(整数…进度){
//更新用户界面或进度条
}
@凌驾
PostExecute上受保护的无效(已返回)
//在此再次返回UI线程以更新视图或取消进度条等
//这将在任务完成后*执行
//它从doInBackground()的返回中接收参数,因此您可以在更新UI时使用该参数。
}
}
经验法则:
- 网络(或其他I/O或长时间运行)代码进入
,在后台线程中执行doInBackground()
- UI代码进入
,后台操作完成后,UI线程将立即执行该代码onPostExecute()
button.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
AsyncTask<Integer, Void, Pollen> loadPollen = new AsyncTask<Integer, Void, Pollen>()
{
@Override
protected Pollen doInBackground(Integer... params)
{
return new Pollen(params[0]);
}
@Override
protected void onPostExecute(Pollen result)
{
textview.setText(result.getCity());
}
};
loadPollen.execute(19104);
}
});
button.setOnClickListener(新视图.OnClickListener()
{
@凌驾
公共void onClick(视图v)
{
AsyncTask LoadPolen=新建AsyncTask()
{
@凌驾
受保护的doInBackground(整数…参数)
{
返回新花粉(参数[0]);
}
@凌驾
受保护的void onPostExecute(结果)
{
setText(result.getCity());
}
};
执行(19104);
}
});
Hi Rod。非常感谢您的回复。我假设RetrievePollenTask
在我的Fragment
类中,对吗?如果不这样做,我就无法访问textview
对象。@如果您将textview作为一个全局变量,这样您就可以通过内部类引用它,或者在Asynctask中创建一个构造函数,并将textview作为一个参数传递出去,我的天哪。非常感谢你。你解决了一个我花了三天时间才弄明白的问题。非常感谢你。你介意向我解释一下你是怎么决定做的吗?对不起,我不明白。。。您的意思是“关于使用AsyncTask”还是“关于此特定代码段”?请不要使用日志或代码的屏幕截图,请将日志和缩进/格式粘贴为代码。
button.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
RetrievePollenTask object = new RetrievePollenTask();
object.execute(19104);
}
});
public class RetrievePollenTask extends AsyncTask<Integer, Void, Pollen>
{
protected Pollen doInBackground(String... params)
{
Pollen pollenObject = new Pollen(19104);
return pollenObject;
}
protected void onPostExecute(Pollen result) {
textview.setText(pollenObject.getCity());
}
}
class RetrievePollenTask extends AsyncTask<String, Integer, Pollen>
{
@Override
protected void onPreExecute() {
// set up a ProgressBar or other UI action here *before* the task runs
}
@Override
protected Pollen doInBackground(String... params)
{
// perform your separate non UI thread actions here
// call publishProgress(int) to update your UI periodically
return pollenObject;
}
@Override
protected void onProgessUpdate(Integer... progress) {
// update your UI or ProgressBar
}
@Override
protected void onPostExectute(Pollen resultReturned)
// back to the UI thread again here to update Views or cancel your ProgressBar etc
// this executes *after* your task has completed
// it receives its argument from the return of doInBackground() so you can use that when updating your UI.
}
}
button.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
AsyncTask<Integer, Void, Pollen> loadPollen = new AsyncTask<Integer, Void, Pollen>()
{
@Override
protected Pollen doInBackground(Integer... params)
{
return new Pollen(params[0]);
}
@Override
protected void onPostExecute(Pollen result)
{
textview.setText(result.getCity());
}
};
loadPollen.execute(19104);
}
});