0

我制作了从 json 获取图像路径的 gridview 应用程序。我第一次在 SimpleAdapter 上创建我只想让我的 gridview 以可绘制的形式显示图像。但是当我运行我的应用程序时,它会在 onPostExecute 中显示一个错误。

如何使用可绘制图像或来自 json 的图像在 gridview 中显示图像?

public class MainActivity extends Activity {

String strUrl = "http://192.168.10.104/adchara1/";
GridView gridView;

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

    // Creating a new non-ui thread task to download json data
    DownloadTask downloadTask = new DownloadTask();

    // Starting the download process
    downloadTask.execute(strUrl);

    gridView = (GridView) findViewById(R.id.lv_countries);        
    gridView.setOnItemClickListener(new OnItemClickListener() {

        public void onItemClick(AdapterView<?> parent, View v, int positon,
                long id) {
             HashMap<String, Object> hm = (HashMap<String, Object>) gridView.getAdapter().getItem(positon);
             String imgPath = (String) hm.get("photo"); //get downloaded image path
             Intent i = new Intent(MainActivity.this, DisplayActivity.class);
             i.putExtra("ClickedImagePath", imgPath ); //put image link in intent.
             startActivity(i);
        }
    });
}

/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException{
  String data = "";
  InputStream iStream = null;

    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(strUrl);
    ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(param));
        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        iStream = httpEntity.getContent();
    } catch (Exception e) {
        Log.e("log_tag", "Error in http connection " + e.toString());
    }
    try {
        BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
        StringBuilder sb = new StringBuilder();
        String line = "";
        while((line = br.readLine()) != null){
            sb.append(line + "\n");
        }
        iStream.close();
        data = sb.toString();
    } catch (Exception e) {
        Log.e("log_tag", "Error converting result " + e.toString());
    }
    return data;
}

/** AsyncTask to download json data */
private class DownloadTask extends AsyncTask<String, Integer, String>{
     String data = "";
     InputStream iStream = null;
    @Override
    protected String doInBackground(String... url) {
        try{
            data = downloadUrl(url[0]);
        }catch(Exception e){
            Log.d("Background Task",e.toString());
        }
        return data;
    }

    @Override
    protected void onPostExecute(String result) {

        // The parsing of the xml data is done in a non-ui thread
        GridViewLoaderTask gridViewLoaderTask = new GridViewLoaderTask();

        // Start parsing xml data
        gridViewLoaderTask.execute(result);
    }
}

/** AsyncTask to parse json data and load ListView */
private class GridViewLoaderTask extends AsyncTask<String, Void, SimpleAdapter>{

    JSONObject jObject;
    // Doing the parsing of xml data in a non-ui thread
    @Override
    protected SimpleAdapter doInBackground(String... strJson) {

        try{
            jObject = new JSONObject(strJson[0]);
            CountryJSONParser countryJsonParser = new CountryJSONParser();
            countryJsonParser.parse(jObject);
        }catch(Exception e){
            Log.d("JSON Exception1",e.toString());
        }

        // Instantiating json parser class
        CountryJSONParser countryJsonParser = new CountryJSONParser();

        // A list object to store the parsed countries list
        List<HashMap<String, Object>> countries = null;

        try{
            // Getting the parsed data as a List construct
            countries = countryJsonParser.parse(jObject);
        }catch(Exception e){
            Log.d("Exception",e.toString());
        }

        // Keys used in Hashmap
        String[] from = { "frame","photo"};

        // Ids of views in listview_layout
        int[] to = { R.id.iv_frame,R.id.iv_photo};

        // Instantiating an adapter to store each items
        // R.layout.listview_layout defines the layout of each item
       // SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), countries, R.layout.lv_layout, from, to);
        SimpleAdapter adapter = new SimpleAdapter(getApplicationContext());
        return adapter;

    }

    /** Invoked by the Android on "doInBackground" is executed */
    protected void onPostExecute(SimpleAdapter adapter) {

        gridView.setAdapter(adapter);

        for(int i=0;i<adapter.getCount();i++){
            HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(i);
            String frameUrl = (String) hm.get("frame_path");
            String imgUrl = (String) hm.get("photo_path");
            ImageLoaderTask imageLoaderTask = new ImageLoaderTask();

            HashMap<String, Object> hmDownload = new HashMap<String, Object>();
            hm.put("frame_path", frameUrl);
            hm.put("photo_path",imgUrl);
            hm.put("position", i);

            // Starting ImageLoaderTask to download and populate image in the listview
            imageLoaderTask.execute(hm);
        }
    }
} 

public class SimpleAdapter extends BaseAdapter{
    Context myContext;
    public SimpleAdapter(Context _myContext){
        myContext = _myContext;
    }

    @Override
    public int getCount() {
        return 6;
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        if(view == null){
            LayoutInflater li = getLayoutInflater();
            view = li.inflate(R.layout.lv_layout, null);

            ImageView iv = (ImageView) view.findViewById(R.id.iv_photo);
            iv.setImageResource(R.drawable.ic_launcher);
        }
        return view;
    }

}

    /** AsyncTask to download and load an image in ListView */
    private class ImageLoaderTask extends AsyncTask<HashMap<String, Object>, Void, HashMap<String, Object>>{

        @Override
        protected HashMap<String, Object> doInBackground(HashMap<String, Object>... hm) {

            InputStream iStream = null;
            String imgUrl;
            String frameUrl;
            imgUrl = (String) hm[0].get("photo_path");
            frameUrl = (String) hm[0].get("frame_path");
            int position = (Integer) hm[0].get("position");

            URL url;
            URL urlFrame;
            try {
                url = new URL(imgUrl);
                urlFrame = new URL(frameUrl);
                // Creating an http connection to communicate with url
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

                // Connecting to url
                urlConnection.connect();

                // Reading data from url
                iStream = urlConnection.getInputStream();

                // Getting Caching directory
                File cacheDirectory = getBaseContext().getCacheDir();

                // Temporary file to store the downloaded image
                File tmpFile = new File(cacheDirectory.getPath() + "/wpta_"+ position + ".png");

                // The FileOutputStream to the temporary file
                FileOutputStream fOutStream = new FileOutputStream(tmpFile);

                // Creating a bitmap from the downloaded inputstream
                Bitmap b = BitmapFactory.decodeStream(iStream);

                // Writing the bitmap to the temporary file as png file
                b.compress(Bitmap.CompressFormat.PNG, 100, fOutStream);

                // Flush the FileOutputStream
                fOutStream.flush();

                // Close the FileOutputStream
                fOutStream.close();

                // Create a hashmap object to store image path and its position in the listview
                HashMap<String, Object> hmBitmap = new HashMap<String, Object>();

                // Storing the path to the temporary image file
                hmBitmap.put("photo", tmpFile.getPath());
                hmBitmap.put("frame", tmpFile.getPath());

                // Storing the position of the image in the listview
                hmBitmap.put("position", position);

                // Returning the HashMap object containing the image path and position
                return hmBitmap;
            } catch (MalformedURLException e) {
                return null;
            } catch (FileNotFoundException e) {
                return null;
            } catch (IOException e) {
                return null;
            }
        }

    @Override
    protected void onPostExecute(HashMap<String, Object> result) {
        // Getting the path to the downloaded image
        String path = (String) result.get("photo");
        String framePath = (String) result.get("frame");
        // Getting the position of the downloaded image
        int position = (Integer) result.get("position");

        // Getting adapter of the listview
        SimpleAdapter adapter = (SimpleAdapter ) gridView.getAdapter();

        // Getting the hashmap object at the specified position of the listview
        HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(position);

        // Overwriting the existing path in the adapter
        hm.put("photo",path);
        hm.put("frame", framePath);
        // Noticing listview about the dataset changes
        adapter.notifyDataSetChanged();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}
}

JSONParser.java

public class CountryJSONParser {

// Receives a JSONObject and returns a list
public List<HashMap<String,Object>> parse(JSONObject jObject){

    JSONArray jsonArray = null;
    try {
        // Retrieves all the elements in the 'countries' array
        jsonArray = jObject.getJSONArray("countries");
    } catch (JSONException e) {
        e.printStackTrace();
    }

    // Invoking getCountries with the array of json object
    // where each json object represent a country
    return getCountries(jsonArray);
}

private List<HashMap<String, Object>> getCountries(JSONArray jCountries){
    int countryCount = jCountries.length();
    List<HashMap<String, Object>> countryList = new ArrayList<HashMap<String,Object>>();
    HashMap<String, Object> country = null;

    // Taking each country, parses and adds to list object
    for(int i=0; i<countryCount;i++){
        try {
            // Call getCountry with country JSON object to parse the country
            country = getCountry((JSONObject)jCountries.get(i));
            countryList.add(country);

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    return countryList;
}

// Parsing the Country JSON object
private HashMap<String, Object> getCountry(JSONObject jCountry){

    HashMap<String, Object> country = new HashMap<String, Object>();

    String photo="";
    String frame ="";

    try {
        photo = jCountry.getString("photo");
        frame = jCountry.getString("frame");

        country.put("frame", R.drawable.blank);
        country.put("frame_path", frame);

        country.put("photo", R.drawable.blank);
        country.put("photo_path", photo);

    } catch (JSONException e) {
        e.printStackTrace();
    }
    return country;
}

}

logcat 中的错误

11-02 08:26:48.118: W/dalvikvm(11384): threadid=1: thread exiting with uncaught exception (group=0x40bee1f8)
11-02 08:26:48.141: E/AndroidRuntime(11384): FATAL EXCEPTION: main
11-02 08:26:48.141: E/AndroidRuntime(11384): java.lang.NullPointerException
11-02 08:26:48.141: E/AndroidRuntime(11384):    at com.myapp.MainActivity$GridViewLoaderTask.onPostExecute(MainActivity.java:187)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at com.myapp.MainActivity$GridViewLoaderTask.onPostExecute(MainActivity.java:1)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at android.os.AsyncTask.finish(AsyncTask.java:602)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at android.os.AsyncTask.access$600(AsyncTask.java:156)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at android.os.Looper.loop(Looper.java:137)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at android.app.ActivityThread.main(ActivityThread.java:4514)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at java.lang.reflect.Method.invokeNative(Native Method)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at java.lang.reflect.Method.invoke(Method.java:511)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
11-02 08:26:48.141: E/AndroidRuntime(11384):    at dalvik.system.NativeStart.main(Native Method)

显现

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"/>

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main"
        android:configChanges="orientation|screenSize" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity 
        android:name=".DisplayActivity">

    </activity>
</application>

4

2 回答 2

1

这是由于 GridView 引发的 NullPointerException。因为您在创建 gridview 对象之前开始下载任务,并且在创建对象时,onPostExecute() 被调用并且它正在引发错误。您首先创建 gridview 对象并调用 DownloadTask。我从您的代码中发现了该错误,希望对您有所帮助。

于 2012-11-02T04:03:49.350 回答
0

写在下面的代码行

// Creating a new non-ui thread task to download json data
DownloadTask downloadTask = new DownloadTask();

// Starting the download process
downloadTask.execute(strUrl);

gridView = (GridView) findViewById(R.id.lv_countries);

它会解决你的问题。

于 2012-11-02T05:06:58.400 回答