【发布时间】:2014-06-01 12:15:32
【问题描述】:
我从 AsyncTask1 调用了 AsyncTask2...这是我的“场景”:
- AsyncTask1 下载一个 rss 提要,解析 xml,然后在 doInBackground 方法中为每个识别的项目创建并执行 AsyncTask2。
- doInBackground 方法中的 AsyncTask2 下载从 AsyncTask1 传递的项目的附件 url 属性,并在 onPostExecute 方法中将该项目添加到全局项目数组中,并将项目的更改通知给关联的适配器。
它运行良好并且没有崩溃,为什么? AsyncTasks 应该从 UI 线程 (threading rules) 运行,现在我对这个假设有点困惑。
抱歉英语不好,我希望问题足够清楚。
编辑 这里有一些代码... DownloadRssAsyncTask = AsyncTask2, RssAsyncTask = AsyncTask1
public class ParseActivity extends Activity {
public class FeedItemAdapter extends ArrayAdapter<FeedItem> {
int resource;
public FeedItemAdapter(Context context, int resource, List<FeedItem> items) {
super(context, resource, items);
this.resource = resource;
}
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout myView;
FeedItem item = getItem(position);
if (convertView == null) {
myView = new LinearLayout(getContext());
String inflaterService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li = (LayoutInflater) getContext().getSystemService(inflaterService);
li.inflate(resource, myView, true);
} else {
myView = (LinearLayout) convertView;
}
TextView titleFeedItem = (TextView) myView.findViewById(R.id.itemTitle);
TextView dateFeedItem = (TextView) myView.findViewById(R.id.itemDate);
ImageView imageFeedItem = (ImageView) myView.findViewById(R.id.imageThumb);
titleFeedItem.setText(item.mTitle);
dateFeedItem.setText(item.mPubDate);
imageFeedItem.setImageBitmap(item.bitmapEnclosure);
return myView;
}
}
private class DownloadRssAsyncTask extends AsyncTask<FeedItem, Void, FeedItem> {
@Override
protected FeedItem doInBackground(FeedItem... params) {
FeedItem item = params[0];
if (item.mEnclosure == null) {
Log.i("info: ", "no enclosure tag");
item.bitmapEnclosure = null;
return item;
}
try {
URL imageUrl = new URL(item.mEnclosure);
item.bitmapEnclosure = BitmapFactory.decodeStream(imageUrl.openStream());
} catch (IOException e) {
Log.e("error", "download image resource error: "+item.mEnclosure);
item.bitmapEnclosure = null;
}
return item;
}
@Override
protected void onPostExecute(FeedItem result) {
items.add(result);
arrayAdapter.notifyDataSetChanged();
dbHelper.putItem(result.mGuid, result.mTitle, result.mDescription, result.mEnclosure, result.mPubDate);
}
}
private class RssAsyncTask extends AsyncTask<String, Integer, Void> {
@Override
protected Void doInBackground(String... params) {
int dimParams = params.length;
for (int i=0; i<dimParams; i++) {
Log.i("doInBackground", "rss feed num "+ (i+1) + " of "+ dimParams+ ": " + params[i]);
refreshFeed(params[i]);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
Log.i("onPostExecute in RssAsyncTask", "notifyDataSetChanged");
}
}
public static class FeedItem {
public String mAuthor;
public String mCategory;
public String mComments;
public String mDescription; //r
public String mEnclosure;
public Bitmap bitmapEnclosure;
public String mGuid;
public String mLink; //r
public String mPubDate;
public String mSource;
public String mTitle; //r
public FeedItem() {
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return
"Data: "+mPubDate+
"\nLink:\n"+mLink+
"\nAutore:\n"+mAuthor+
"\nTitolo:\n"+mTitle+
"\nEnclosure:\n"+mEnclosure;
}
}
private FeedReaderDbHelper dbHelper;
private FeedItemAdapter arrayAdapter;
private ArrayList<FeedItem> items;
private ListView myListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parse);
items = new ArrayList<FeedItem>();
new ArrayList<FeedItem>();
myListView = (ListView) findViewById(R.id.myListView);
arrayAdapter = new FeedItemAdapter(this, R.layout.feed_item, items);
myListView.setAdapter(arrayAdapter);
dbHelper = new FeedReaderDbHelper(this);
//RssAsyncTask: download and parsing rss feed
new RssAsyncTask().execute(getString(R.string.my_feed));
}
public void refreshFeed(String feed) {
final String TAG = "refreshFeed";
Log.i(TAG, feed);
URL url = null;
try {
url = new URL(feed);
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
int httpCode = httpConnection.getResponseCode();
if (httpCode == HttpURLConnection.HTTP_OK) {
processFeed(httpConnection.getInputStream());
} else {
Log.i(TAG, httpCode + httpConnection.getResponseMessage());
}
} catch (MalformedURLException e1) {
Log.i(TAG, "MalformedUrlException in " + feed);
} catch (IOException e) {
Log.i(TAG, "IOException in " + url.toString());
}
}
private void processFeed(InputStream inputStream ) {
final String TAG = "processFeed";
final String ITEM = "item";
final String AUTHOR ="author";
final String TITLE ="title";
final String CATEGORY ="category";
final String COMMENTS ="comments";
final String DESCRIPTION ="description";
final String GUID ="guid";
final String LINK ="link";
final String PUBDATE="pubDate";
final String SOURCE ="source";
final String ENCLOSURE = "enclosure";
Log.i(TAG, inputStream.toString());
XmlPullParserFactory pullParserFact;
try {
pullParserFact = XmlPullParserFactory.newInstance();
pullParserFact.setNamespaceAware(true);
XmlPullParser pullParser = pullParserFact.newPullParser();
pullParser.setInput(inputStream, null);
int eventType = pullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && pullParser.getName().equals(ITEM)){
final FeedItem item = new FeedItem();
eventType = pullParser.next();
while ( !(eventType == XmlPullParser.END_TAG && pullParser.getName().equals(ITEM)) ) {
if ( eventType == XmlPullParser.START_TAG ) {
String name = pullParser.getName();
switch (name) {
case AUTHOR:
item.mAuthor = pullParser.nextText();
break;
case TITLE:
item.mTitle = pullParser.nextText();
break;
case CATEGORY:
item.mCategory = pullParser.nextText();
break;
case COMMENTS:
item.mComments = pullParser.nextText();
break;
case DESCRIPTION:
item.mDescription = pullParser.nextText();
break;
case GUID:
item.mGuid = pullParser.nextText();
break;
case LINK:
item.mLink = pullParser.nextText();
break;
case PUBDATE:
item.mPubDate = pullParser.nextText();
break;
case SOURCE:
item.mSource = pullParser.nextText();
break;
case ENCLOSURE:
item.mEnclosure = pullParser.getAttributeValue(null, "url");
default:
break;
}
}
eventType = pullParser.next();
}
//download the optional enclosure resource and update UI
new DownloadRssAsyncTask().execute(item);
}
eventType = pullParser.next();
}
} catch (XmlPullParserException e) {
Log.i(TAG, "XmlPullparserException");
} catch (IOException e) {
Log.i(TAG, "IOException");
}
}
}
【问题讨论】:
-
“线程规则”提到,从 UI 线程运行是从 Jelly Bean 自动完成的。
-
@pingw33n:在线程规则中...
-
如果您包含您的代码会有所帮助。您是否专门在
AsyncTask1的doInBackground()方法中创建并执行了这个AsyncTask2?抽象AsyncTask中不是doInBackground的每个方法都在 UI 线程上运行。 -
另外,这些只是线程规则。如果您想要定义的行为,这是您必须遵循的。如果您在这些规则之外使用它,它不会必然因异常而失败,但您可能会得到一些未定义的行为。
标签: java android multithreading android-asynctask adapter