-1

我有这个代码,我可以从 XML 解析,但我在设置适配器时出错,谁能帮我解决这个问题。

提前致谢

这是我的代码

public class TestJSON extends Activity{

    public static ListView lv;
    public static ProgressDialog pDialog;
    public static LazyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_json_view);

        new AsyncInitial().execute();
        // Showing progress dialog before sending http request
        pDialog = new ProgressDialog(this);
        pDialog.setMessage("Please wait..");
        pDialog.setIndeterminate(true);
        pDialog.setCancelable(false);
        pDialog.show();

        lv = (ListView)findViewById(R.id.list);
        //lv.setAdapter(new ArrayAdapter(getApplicationContext(), android.R.layout.simple_expandable_list_item_1, items));
    }

    private class AsyncInitial extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {


            @Override
            protected void onPreExecute() {
            }

            @Override
            protected ArrayList<HashMap<String, String>> doInBackground(Void... arg0) {

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

                try {
                    //if (vid_num <= 0) {
                    // Get a httpclient to talk to the internet
                    HttpClient client = new DefaultHttpClient();
                    // Perform a GET request to YouTube for a JSON list of all the videos by a specific user
                    //https://gdata.youtube.com/feeds/api/videos?author="+username+"&v=2&alt=jsonc
                    HttpUriRequest request = new HttpGet("http://gdata.youtube.com/feeds/api/playlists/SP86E04995E07F6BA8?v=2&start-index=1&max-results=50&alt=jsonc");
                    // Get the response that YouTube sends back
                    HttpResponse response = client.execute(request);
                    // Convert this response into a readable string
                    String jsonString = StreamUtils.convertToString(response.getEntity().getContent());
                    // Create a JSON object that we can use from the String
                    JSONObject json = new JSONObject(jsonString);

                    // For further information about the syntax of this request and JSON-C
                    // see the documentation on YouTube http://code.google.com/apis/youtube/2.0/developers_guide_jsonc.html

                    // Get are search result items
                    JSONArray jsonArray = json.getJSONObject("data").getJSONArray("items");

                    // Get the total number of video
                    //String vid_num = json.getJSONObject("data").getString("totalItems");
                    //System.out.println("vid_num-------->"+  vid_num);

                    // Loop round our JSON list of videos creating Video objects to use within our app
                    for (int i = 0; i < jsonArray.length(); i++) {

                        HashMap<String, String> map = new HashMap<String, String>();
                        JSONObject jsonObject = jsonArray.getJSONObject(i);

                        // The title of the video
                        String title = jsonObject.getJSONObject("video").getString("title");
                        System.out.println("Title-------->"+  title);


                        // The url link back to YouTube, this checks if it has a mobile url
                        // if it doesnt it gets the standard url
                        String url;
                        try {
                            url = jsonObject.getJSONObject("video").getJSONObject("player").getString("mobile");//
                            System.out.println("url-------->"+  url);
                        } catch (JSONException ignore) {
                            url = jsonObject.getJSONObject("video").getJSONObject("player").getString("default");
                            System.out.println("url-------->"+  url);
                        }

                        // A url to the thumbnail image of the video
                        // We will use this later to get an image using a Custom ImageView
                        //String TAG_thumbUrl = jsonObject.getJSONObject("video").getJSONObject("thumbnail").getString("sqDefault");
                        //System.out.println("thumbUrl-------->"+  thumbUrl);

                        String video_id = jsonObject.getJSONObject("video").getString("id");
                        System.out.println("video_id-------->"+  video_id);

                        map.put(title, title);
                        //map.put(url, url);
                        map.put(video_id, video_id);

                        menuItems.add(map); 
                    }

                    adapter = new LazyAdapter(TestJSON.this,menuItems);    
                    lv.setAdapter(adapter);

                } catch (ClientProtocolException e) {
                //Log.e("Feck", e);
                } catch (IOException e) {
                //Log.e("Feck", e);
                } catch (JSONException e) {
                //Log.e("Feck", e);
                }

                return menuItems;
            }


            @Override
            protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
                // TODO Auto-generated method stub
                //super.onPostExecute(result);

                pDialog.dismiss();
            }


    }

}

适配器

public class LazyAdapter extends BaseAdapter {

    private Activity activity;
    private static LayoutInflater inflater;
    private ArrayList<HashMap<String, String>> data;

    public LazyAdapter(TestJSON testJSON, ArrayList<HashMap<String, String>> menuItems) {
        activity = testJSON;
        data = menuItems;
        System.out.println("Hash-------->");
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override   
    public long getItemId(int position) {
        return position;
    }

    public static class ViewHolder {
       }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //ViewHolder holder;

        View vi=convertView;
        if(convertView==null)vi = inflater.inflate(R.layout.list_row, null);

        TextView title = (TextView)vi.findViewById(R.id.title); 
        TextView id = (TextView)vi.findViewById(R.id.artist);


        HashMap<String, String> menuItems = new HashMap<String, String>();
        menuItems = data.get(position);

        title.setText(menuItems.get("title"));
        id.setText(menuItems.get("video_id"));

        System.out.println("Adapter Title from Hash-------->"+  title);
        System.out.println("Adapter video_id from Hash-------->"+  id);
        return vi;
    }

}

这是日志猫的错误

07-08 17:46:39.567: E/AndroidRuntime(13049): FATAL EXCEPTION: AsyncTask #1
07-08 17:46:39.567: E/AndroidRuntime(13049): java.lang.RuntimeException: An error occured while executing doInBackground()
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at java.lang.Thread.run(Thread.java:856)
07-08 17:46:39.567: E/AndroidRuntime(13049): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4609)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:867)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:4066)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.view.View.invalidate(View.java:10250)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.view.View.invalidate(View.java:10205)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.widget.AbsListView.resetList(AbsListView.java:1954)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.widget.ListView.resetList(ListView.java:502)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.widget.ListView.setAdapter(ListView.java:442)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at com.jpact.youtubeapp.TestJSON$AsyncInitial.doInBackground(TestJSON.java:122)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at com.jpact.youtubeapp.TestJSON$AsyncInitial.doInBackground(TestJSON.java:1)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
07-08 17:46:39.567: E/AndroidRuntime(13049):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-08 17:46:39.567: E/AndroidRuntime(13049):    ... 5 more
4

4 回答 4

3
 adapter = new LazyAdapter(TestJSON.this,menuItems);    
 lv.setAdapter(adapter);

Updating ui fro doInBackground is not possible. this causes the exception.

You need to update in onPostExecute or use runOnUiThread.

doInbackground is invoked on the background thread. so you can't update ui from background thread. Ui should be updated on ui thread.

You can return result in doInBackground. The result of doInBackGround computation is a parameter toonPostExecute . SO return result in doInbackground and update ui in onPostexecute.

 @Override
 protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
  super.onPostExecute(result);
  pDialog.dismiss();
  adapter = new LazyAdapter(TestJSON.this,result);    
  lv.setAdapter(adapter); 
 }
于 2013-07-08T09:59:32.733 回答
0

Put the following code:

adapter = new LazyAdapter(TestJSON.this,menuItems);    
lv.setAdapter(adapter);

into the following method:

@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
    // TODO Auto-generated method stub
    //super.onPostExecute(result);

    pDialog.dismiss();
}
于 2013-07-08T10:00:08.223 回答
0

当我看到您的代码时,您正在尝试为您的惰性列表设置适配器

doInBackground(Void... arg0) {
    //Do not set your adapter here in this method

}

相反,您可以将适配器设置为

onPostExecute(Void result){
adapter = new LazyAdapter(TestJSON.this,menuItems);    
                lv.setAdapter(adapter);
}

并删除负责在 doInBackground 方法中设置适配器的行。永远不要尝试从后台线程处理 UiThread。它总是会抛出异常。可能这会对你有所帮助。

于 2013-07-08T10:06:26.683 回答
0

您不能在doInBackground()方法中设置适配器。Adapter 只能从 UI 线程中设置。

您可以将代码移动到该onPostExecute()方法或使用该runOnUiThread(action)方法。

于 2013-07-08T10:02:03.213 回答