异步加载JSON listview

时间:2012-10-27 10:01:18

标签: android android-layout android-intent android-asynctask

你好我有这个代码,它给了我android 3和4设备上的错误。 我知道我可以用异步解决这个问题,但我之前没有使用同步任务,也不知道这是如何工作的。有人可以给我一些我的代码或建议如何实现它的例子?

我的代码:

package com.wemait.obd.emmen;

import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.wemait.obd.emmen.JSONParser;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class Nieuws extends Activity {


// url om request te maken
private static String URL = "http://www.iappministrator.com/OBDE/webservice/android_news_items.php";

// JSON Node namen
static final String TAG_ITEMS = "items";
static final String TAG_TITLE = "title";
static final String TAG_MESSAGE = "message";
static final String TAG_DATE = "date";
static final String TAG_IMAGES = "images";

// Nieuws JSONArray
JSONArray newsArray = null;

ListView list;
LazyAdapter adapter;

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

    // Hashmap voor listView
    final ArrayList<HashMap<String, String>> newsList = new ArrayList<HashMap<String, String>>();

    // Maak een JSON Parser instance
    JSONParser jParser = new JSONParser();

    // Pakt JSON string uit URL
    JSONObject json = jParser.getJSONFromUrl(URL);

    try{
        // Pakt de Array van Nieuwsartikelen
        newsArray = json.getJSONArray(TAG_ITEMS);

        // Loop door alle Nieuwsartikels
        for(int i=0; i < newsArray.length(); i++){
            JSONObject c = newsArray.getJSONObject(i);

            // Het plaatsen van elk json item in variabele
            String title = c.getString(TAG_TITLE);
            String message = c.getString(TAG_MESSAGE);
            //String date = c.getString(TAG_DATE);
            String images = c.getString(TAG_IMAGES);

            // maak een nieuwe HashMap
            HashMap<String, String> map = new HashMap<String, String>();

            // voeg elk item child node in de Hashmap -> value
            map.put(TAG_TITLE, title);
            map.put(TAG_MESSAGE, message);
            //map.put(TAG_DATE, date);
            map.put(TAG_IMAGES, images);


            // voeg de HashList toe aan ArrayList
            newsList.add(map);
        }
    } catch(JSONException e){
        e.printStackTrace();
    }


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

    adapter=new LazyAdapter(this, newsList, R.layout.list_row, 
            new String[]{TAG_TITLE, TAG_MESSAGE, TAG_DATE, TAG_IMAGES}, new int[] {
            R.id.title, R.id.artist, R.id.duration, R.id.list_image});        
    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) {
              HashMap<String, String> map = newsList.get(position);

             Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
            //Intent in = new Intent(SingleMenuItemActivity.this, org.scout.android.library.LibraryDetail.class);
            in.putExtra(TAG_TITLE, map.get(TAG_TITLE));
            in.putExtra(TAG_MESSAGE, map.get(TAG_MESSAGE));                         
            in.putExtra(TAG_DATE, map.get(TAG_DATE));
            in.putExtra(TAG_IMAGES, map.get(TAG_IMAGES));

            startActivity(in);
        /* old code public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {


            String title = ((TextView) view.findViewById(R.id.title)).getText().toString();
            String date = ((TextView) view.findViewById(R.id.duration)).getText().toString();
            String message = ((TextView) view.findViewById(R.id.artist)).getText().toString();
            //String images = ((TextView) view.findViewById(R.id.list_image)).getText().toString();
            //ImageView thumb_image = (ImageView) view.findViewById(R.id.thumbnail); // thumb image
            String images = ((ImageView)view.findViewById(R.id.list_image)).getImageMatrix().toString();
            //String images = ((ImageView)view.findViewById(R.id.list_image)).toString();
            //String images = ((ImageView)view.findViewById(R.id.list_image)).getContext().toString();

            // Start de nieuwe intent

            Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
            //Bitmap bitmap = (Bitmap) in.getParcelableExtra(TAG_IMAGES);

            in.putExtra(TAG_TITLE, title);
            in.putExtra(TAG_DATE, date);
            in.putExtra(TAG_MESSAGE, message);
            in.putExtra(TAG_IMAGES, images);
            startActivity(in);*/

        }
    });     
}   

}

我收到的错误:

 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.wemait.obd.emmen/com.wemait.obd.emmen.Nieuws}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
at android.app.ActivityThread.access$600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
at java.net.InetAddress.getAllByName(InetAddress.java:220)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
at com.wemait.obd.emmen.JSONParser.getJSONFromUrl(JSONParser.java:38)
at com.wemait.obd.emmen.Nieuws.onCreate(Nieuws.java:53)
at android.app.Activity.performCreate(Activity.java:4470)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)

我的适配器类:

    package com.wemait.obd.emmen;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class LazyAdapter extends BaseAdapter {

    private Activity activity;
    private ArrayList<HashMap<String, String>> data;
    private static LayoutInflater inflater=null;
    public ImageLoader imageLoader; 

    public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d, int listRow, String[] strings, int[] is) {
        activity = a;
        data=d;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader=new ImageLoader(activity.getApplicationContext());
    }

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

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

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

    public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;
        if(convertView==null)
            vi = inflater.inflate(R.layout.list_row, null);

        TextView title = (TextView)vi.findViewById(R.id.title); // title
        TextView artist = (TextView)vi.findViewById(R.id.artist); // artist name
        TextView duration = (TextView)vi.findViewById(R.id.duration); // duration
        ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image); // thumb image

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

        // Setting all values in listview
        title.setText(song.get(CustomizedListView.TAG_TITLE));
        artist.setText(song.get(CustomizedListView.TAG_MESSAGE));
        duration.setText(song.get(CustomizedListView.TAG_DATE));
        imageLoader.DisplayImage(song.get(CustomizedListView.TAG_IMAGES), thumb_image);
        return vi;
    }
}

2 个答案:

答案 0 :(得分:2)

Android 3和4有此限制。您无法在主线程上运行任何与网络相关的任务。您必须为此创建单独的线程或使用异步任务。我会推荐AsynTask但是如果你想通过线程解决这个问题,那么使用线程和处理程序来实现它。如果您使用AsynTask,那么您的代码就会如此:)

public class Nieuws extends Activity{
private static String URL = "http://www.iappministrator.com/OBDE/webservice/android_news_items.php";

// JSON Node namen
static final String TAG_ITEMS = "items";
static final String TAG_TITLE = "title";
static final String TAG_MESSAGE = "message";
static final String TAG_DATE = "date";
static final String TAG_IMAGES = "images";

// Nieuws JSONArray
JSONArray newsArray = null;

ListView list;
LazyAdapter adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.nieuws);
    list=(ListView)findViewById(R.id.list);

    new GetJSONData().execute();

}

class GetJSONData extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>>{

@Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... arg0) {
    // Hashmap voor listView
    final ArrayList<HashMap<String, String>> newsList = new ArrayList<HashMap<String, String>>();

    // Maak een JSON Parser instance
    JSONParser jParser = new JSONParser();

    // Pakt JSON string uit URL
    JSONObject json = jParser.getJSONFromUrl(URL);

    try{
        // Pakt de Array van Nieuwsartikelen
        newsArray = json.getJSONArray(TAG_ITEMS);

        // Loop door alle Nieuwsartikels
        for(int i=0; i < newsArray.length(); i++){
            JSONObject c = newsArray.getJSONObject(i);

            // Het plaatsen van elk json item in variabele
            String title = c.getString(TAG_TITLE);
            String message = c.getString(TAG_MESSAGE);
            //String date = c.getString(TAG_DATE);
            String images = c.getString(TAG_IMAGES);

            // maak een nieuwe HashMap
            HashMap<String, String> map = new HashMap<String, String>();

            // voeg elk item child node in de Hashmap -> value
            map.put(TAG_TITLE, title);
            map.put(TAG_MESSAGE, message);
            //map.put(TAG_DATE, date);
            map.put(TAG_IMAGES, images);


            // voeg de HashList toe aan ArrayList
            newsList.add(map);
        }
    } catch(JSONException e){
        e.printStackTrace();
    }
    return newsList;
}
@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {



    adapter=new LazyAdapter(this, result, R.layout.list_row, 
            new String[]{TAG_TITLE, TAG_MESSAGE, TAG_DATE, TAG_IMAGES}, new int[] {
            R.id.title, R.id.artist, R.id.duration, R.id.list_image});        
    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) {
              HashMap<String, String> map = newsList.get(position);

             Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
            //Intent in = new Intent(SingleMenuItemActivity.this, org.scout.android.library.LibraryDetail.class);
            in.putExtra(TAG_TITLE, map.get(TAG_TITLE));
            in.putExtra(TAG_MESSAGE, map.get(TAG_MESSAGE));                         
            in.putExtra(TAG_DATE, map.get(TAG_DATE));
            in.putExtra(TAG_IMAGES, map.get(TAG_IMAGES));

            startActivity(in);

        }
    });
}
}
}

答案 1 :(得分:1)

if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                    .permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }