我目前有一个 Pollen 类,它是我编写的一个类,它使用 JSoup 库来解析 HTML。这里还显示了我的 PlaceholderFragment
类。
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;
}
}
这是我的花粉类(class)。
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();
}
}
}
虽然每次尝试都失败了,但我学到了很多东西。我发现,在使用 onClick
中调用 Pollen
类时,我正在执行一项昂贵的任务。因此,我应该把它放在一个单独的线程中。另外,由于我在主/UI 线程中调用 Pollen 类,因此它会导致我的应用程序崩溃。
我查阅了这个 Stackoverflow 问题来帮助我尝试解决我的问题:How to fix android.os.NetworkOnMainThreadException?
我通过 logcat 中的错误日志发现了我的错误和解决方案,特别是 NetworkOnMainThread
,其中 Android 明确阻止我在 UI 线程上执行任何网络操作。
我的问题是 - 如何将我的 Pollen
类分配到不在我的 UI 类中的单独线程中?
继续我关于 Stackoverflow 线程的教程,我添加了此类。我不知道我在做什么..但我会尽力继续:
abstract class RetrievePollenTask extends AsyncTask<Integer, Void, Pollen>
{
protected Pollen doInBackground(String... params)
{
// TODO Auto-generated method stub
return null;
}
}
最佳答案
是的,您正在尝试在 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());
}
}
您可以将异步任务作为 fragment 的内部类,这样您就不需要在其上传递上下文参数。另外,不要将更新任何 View 放入 doInBackground
中,因为它是一个不同的线程,它将捕获异常。
关于java - 单独线程上的网络相关任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23973612/