我正在尝试为我的应用创建一个RSS阅读器,问题是当我尝试显示我的片段不起作用并抛出异常而无效。
我正在尝试关注此示例:https://androidresearch.wordpress.com/2012/01/21/creating-a-simple-rss-application-in-android/
我怎么能这样做?
RSS阅读器片段
public class RSSReaderFrag extends Fragment implements AdapterView.OnItemClickListener{
private final String TAG = getClass().getSimpleName() + "->";
private ProgressDialog progress;
//listas
private List headlines;
private List links;
private ListView listRSS;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.rss_feed, container, false);
listRSS = (ListView)view.findViewById(R.id.listRSS);
listRSS.setOnItemClickListener(this);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
new AsyncTask<Void, Void, Void>(){
@Override
protected Void doInBackground(Void... params) {
init();
return null;
}
}.execute();
}
/** init RSS */
private void init(){
// Initializing instance variables
headlines = new ArrayList();
links = new ArrayList();
try {
URL url = new URL("http://feeds.pcworld.com/pcworld/latestnews");
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser();
// We will get the XML from an input stream
xpp.setInput(getInputStream(url), "UTF_8");
/* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag.
* However, we should take in consideration that the rss feed name also is enclosed in a "<title>" tag.
* As we know, every feed begins with these lines: "<channel><title>Feed_Name</title>...."
* so we should skip the "<title>" tag which is a child of "<channel>" tag,
* and take in consideration only "<title>" tag which is a child of "<item>"
*
* In order to achieve this, we will make use of a boolean variable.
*/
boolean insideItem = false;
// Returns the type of current event: START_TAG, END_TAG, etc..
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if (xpp.getName().equalsIgnoreCase("item")) {
insideItem = true;
} else if (xpp.getName().equalsIgnoreCase("title")) {
if (insideItem)
headlines.add(xpp.nextText()); //extract the headline
} else if (xpp.getName().equalsIgnoreCase("link")) {
if (insideItem)
links.add(xpp.nextText()); //extract the link of article
}
}else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
insideItem=false;
}
eventType = xpp.next(); //move to next element
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Binding data
ArrayAdapter adapter = new ArrayAdapter(getView().getContext(), android.R.layout.simple_list_item_1, headlines);
listRSS.setAdapter(adapter);
}
private InputStream getInputStream(URL url) {
try {
return url.openConnection().getInputStream();
} catch (IOException e) {
return null;
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Uri uri = Uri.parse((String)links.get(position));
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}
异常
05-14 09:09:58.086 21617-22201/br.com.williarts.radios.provincia E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6818)
at android.view.ViewRootImpl.focusableViewAvailable(ViewRootImpl.java:3335)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:681)
at android.view.View.setFlags(View.java:9397)
at android.view.View.setFocusableInTouchMode(View.java:6168)
at android.widget.AdapterView.checkFocus(AdapterView.java:720)
at android.widget.ListView.setAdapter(ListView.java:471)
at br.com.williarts.radios.provincia.frags.NoticiasFrag.init(NoticiasFrag.java:136)
at br.com.williarts.radios.provincia.frags.NoticiasFrag.access$000(NoticiasFrag.java:36)
at br.com.williarts.radios.provincia.frags.NoticiasFrag$1.doInBackground(NoticiasFrag.java:70)
at br.com.williarts.radios.provincia.frags.NoticiasFrag$1.doInBackground(NoticiasFrag.java:67)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
答案 0 :(得分:1)
您必须将此部分代码移到doInBackground()
函数之外并在UI Thread
中运行:
// Binding data
ArrayAdapter adapter = new ArrayAdapter(getView().getContext(), android.R.layout.simple_list_item_1, headlines);
listRSS.setAdapter(adapter);`
onPostExecute()
中的
仅移动listRSS.setAdapter(adapter);
也足够了,但为清除移动Adapter creation
答案 1 :(得分:1)
如已经评论过,您无法从asynctask的doInBackground方法更新UI线程(在不同的线程中执行),快速解决方案是替换:
// Binding data
ArrayAdapter adapter = new ArrayAdapter(getView().getContext(), android.R.layout.simple_list_item_1, headlines);
listRSS.setAdapter(adapter);
使用:
runOnUiThread(new Runnable() {
@Override
public void run() {
listRSS.setAdapter(adapter);
}
});