【问题标题】:Activity runs fine in on android 2.x but crashes on 3.x and upActivity 在 android 2.x 上运行良好,但在 3.x 及更高版本上崩溃
【发布时间】:2012-11-11 21:43:34
【问题描述】:

我有一个应用程序,其中包含一个 xml Dom 解析器。解析器活动由另一个片段中的按钮激活。当我运行该应用程序时,它在 Gingerbread 上运行良好,但在 Honeycomb 和 Jelly Bean 上,它每次都强制关闭。这是强制关闭时的类信息和日志 cat 文件。如果有人对造成这种情况的原因有任何想法,请告诉我。

我正在尝试启动的课程

 public class CustomizedListView extends SherlockActivity {
// All static variables
static final String URL = "http://treymorgan.net/feed";
// XML node keys
static final String KEY_ID = "channel"; // parent node 
static final String KEY_ITEM = "item";
static final String KEY_TITLE = "title";
static final String KEY_PUB_DATE = "pubDate";
static final String KEY_LINK = "link";

ListView list;
LazyAdapter adapter;

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
        // app icon in action bar clicked; go home
                    Intent intent = new Intent(this, MainActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(intent);
                    return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ActionBar bar = getSupportActionBar();
    bar.setDisplayHomeAsUpEnabled(true);



    final ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

    XMLParser parser = new XMLParser();
    String xml = parser.getXmlFromUrl(URL); // getting XML from URL
    Document doc = parser.getDomElement(xml); // getting DOM element

    NodeList nl = doc.getElementsByTagName(KEY_ITEM);
    // looping through all song nodes <song>
    for (int i = 0; i < nl.getLength(); i++) {
        // creating new HashMap
        HashMap<String, String> map = new HashMap<String, String>();
        Element e = (Element) nl.item(i);
        // adding each child node to HashMap key => value
        map.put(KEY_ITEM, parser.getValue(e, KEY_ITEM));
        map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
        map.put(KEY_PUB_DATE, parser.getValue(e, KEY_PUB_DATE));
        map.put(KEY_LINK, parser.getValue(e, KEY_LINK));

        // adding HashList to ArrayList
        songsList.add(map);
    }


    list=(ListView)findViewById(R.id.list);

    // Getting adapter by passing xml data ArrayList
    adapter=new LazyAdapter(this, songsList);        
    list.setAdapter(adapter);


    // Click event for single list row
    list.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {

            Uri uriUrl = Uri.parse(songsList.get(position).get(KEY_LINK));  
            Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);  
            startActivity(launchBrowser);  



             }

    });
}   
}

原木猫

08-29 03:28:48.603: E/AndroidRuntime(658): FATAL EXCEPTION: main
08-29 03:28:48.603: E/AndroidRuntime(658): java.lang.RuntimeException: Unable to start        activity ComponentInfo{com.threesixteenapps.treymorgan/com.threesixteenapps.treymorgan.CustomizedListView}: android.os.NetworkOnMainThreadException
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.app.ActivityThread.access$600(ActivityThread.java:123)
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.os.Handler.dispatchMessage(Handler.java:99)
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.os.Looper.loop(Looper.java:137)
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.app.ActivityThread.main(ActivityThread.java:4424)
08-29 03:28:48.603: E/AndroidRuntime(658):  at java.lang.reflect.Method.invokeNative(Native Method)
08-29 03:28:48.603: E/AndroidRuntime(658):  at java.lang.reflect.Method.invoke(Method.java:511)
08-29 03:28:48.603: E/AndroidRuntime(658):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-29 03:28:48.603: E/AndroidRuntime(658):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-29 03:28:48.603: E/AndroidRuntime(658):  at dalvik.system.NativeStart.main(Native Method)
08-29 03:28:48.603: E/AndroidRuntime(658): Caused by: android.os.NetworkOnMainThreadException
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
08-29 03:28:48.603: E/AndroidRuntime(658):  at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
08-29 03:28:48.603: E/AndroidRuntime(658):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
08-29 03:28:48.603: E/AndroidRuntime(658):  at java.net.InetAddress.getAllByName(InetAddress.java:220)
08-29 03:28:48.603: E/AndroidRuntime(658):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
08-29 03:28:48.603: E/AndroidRuntime(658):  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
08-29 03:28:48.603: E/AndroidRuntime(658):  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
08-29 03:28:48.603: E/AndroidRuntime(658):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
08-29 03:28:48.603: E/AndroidRuntime(658):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
08-29 03:28:48.603: E/AndroidRuntime(658):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
08-29 03:28:48.603: E/AndroidRuntime(658):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
08-29 03:28:48.603: E/AndroidRuntime(658):  at com.threesixteenapps.treymorgan.XMLParser.getXmlFromUrl(XMLParser.java:45)
08-29 03:28:48.603: E/AndroidRuntime(658):  at com.threesixteenapps.treymorgan.CustomizedListView.onCreate(CustomizedListView.java:64)
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.app.Activity.performCreate(Activity.java:4465)
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
08-29 03:28:48.603: E/AndroidRuntime(658):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
08-29 03:28:48.603: E/AndroidRuntime(658):  ... 11 more

如果需要更多信息,我很乐意为您提供。谢谢你的帮助

【问题讨论】:

标签: android android-listview forceclose


【解决方案1】:

Android 3.0 及更高版本不允许您在 ui 线程 (see this post) 中执行任何网络任务。
解决方案是实现AsyncTaskLoader

编辑:我做了一个快速示例,说明如何在 Activity 中实现 AsyncTask。 我移除了一些部件或用 cmets 替换它们以保持它相当短。只需将其与您的代码合并,它应该可以正常工作(将MyActivity 替换为您自己的等)。

public class MyActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //super onCreate, setup your content, actionbar etc.

        AsyncTask getxml = new MyAsyncTask();
        getxml.execute(URL);
    }

    private class MyAsyncTask extends AsyncTask<String, Integer, Void>{
        private static final int RESULT_GOT_XML = 1;
        private static final int RESULT_FAILED = 0;
        private ArrayList<HashMap<String, String>> asyncList;
        public MyAsyncTask(){
            asyncList = new ArrayList<HashMap<String, String>>();
        }

        @Override
        protected Integer doInBackground(String... url) {

            try{
                XMLParser parser = new XMLParser();
                String xml = parser.getXmlFromUrl(url[0]);
                Document doc = parser.getDomElement(xml);

                NodeList nl = doc.getElementsByTagName(KEY_ITEM);
                for (int i = 0; i < nl.getLength(); i++) {
                    //...perform the parsing and add to list:
                    asyncList.add(map);
                }
            }catch(IOException e){
                Log.e("MyAsync", "could not complete xml retrieval/parsing", e);
                return RESULT_FAILED;
            }
            return RESULT_GOT_XML;
        }

        @Override
        protected void onPostExecute(Integer result) {
            switch (result) {
            case RESULT_FAILED:
                Toast.makeText(MyActivity.this, "Could not get data", Toast.LENGTH_SHORT).show();
                break;
            case RESULT_GOT_XML:
                songsList.addAll(asyncList);
                list=(ListView)findViewById(R.id.list);
                adapter=new LazyAdapter(this, songsList);        
                list.setAdapter(adapter);

                list.setOnItemClickListener(yourclicklistener);
            default:
                Log.wtf("MyAsync","got unexpected result: "+result);
                break;
            }
        }
    }
}

【讨论】:

  • 你知道一个很好的提要解析器教程可以证明这一点吗,我对使用 AsyncTask 还不是很熟悉,希望这将是一个简单的修复,而不必重写大量代码
  • AsyncTask 实际上使用起来非常简单,您只需覆盖doInBackground-方法并将所有网络和解析都放在那里,然后在onPostExecute 方法中更新您的列表。这就是我们所需要的。
  • 冒着听起来像个新手的风险,你把我弄丢了,对不起。我现在可以看到 Async 将是解决此问题的正确方法,只是不确定我现在需要更改什么以使其正常工作,但我将继续研究您在此处所说的内容
  • 感谢您提供的代码,因为这是我第一次处理异步任务,所以在实现它时遇到了一些麻烦,您是否有时间将其移至聊天室并帮助我解决有点这个?
【解决方案2】:
Caused by: android.os.NetworkOnMainThreadException

您正在执行network operation on the main thread,这在最近的 API 中是不允许的。使用 DownloadManager 或将您的 XMLParser 移动到新线程,可能是 AsyncTask。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-05
    • 2012-04-28
    • 1970-01-01
    • 2022-06-24
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    相关资源
    最近更新 更多