我制作了从 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>