我有一个应用程序,可以从服务器(当前是localhost)检索带有图像URL的用户信息。 我能够获取所有信息并将字符串数据放在HashMap中,并将我检索到的url图像解码为位图数组。
我的问题是我在将两者放入自定义ListAdapter时遇到了困难。 我的应用程序在我开始添加图像之前工作正常,我不确定我是否以正确的方式这样做。
第一个类是LIST ACTIVITY所在的位置,以及我从服务器中检索初始信息的位置。
任何帮助都将获得支持
public class AllProductsActivity extends ListActivity {
// Progress Dialog
private ProgressDialog pDialog;
// Creating JSON Parser object
JSONParser jParser = new JSONParser();
//Arrays to hold String Data and Bitmap Data for the custom list adapter
ArrayList<HashMap<String, String>> productsList;
ArrayList<HashMap<String, Bitmap>> listingImages;
// url to get all products list
private static String url_all_products = "http://10.0.2.2/loginform
/get_all_products.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_MENU_LISTING = "menu_listing";
private static final String TAG_PRODUCT_ID = "product_id";
private static final String TAG_NAME = "name";
private static final String TAG_PRODUCT_NAME = "product_name";
private static final String TAG_RATING = "rating";
private static final String TAG_RESTAURANT = "restaurant";
private static final String TAG_LOCATION = "location";
private static final String TAG_IMAGE_PATH = "image_path";
// products JSONArray
JSONArray m_listing = null;
ArrayList<String> imageArray = new ArrayList<String>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_items);
// Hashmap for ListView
productsList = new ArrayList<HashMap<String, String>>();
// Loading products in Background Thread
new LoadAllProducts().execute();
// Get listview
ListView lv = getListView();
// on selecting single product
// launching Edit Product Screen
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String product_id = ((TextView) view.findViewById(R.id.pid)).getText()
.toString();
String pName = ((TextView) view.findViewById(R.id.name)).getText()
.toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(),
ProductReviews.class);
// sending pid to next activity
in.putExtra(TAG_PRODUCT_ID, product_id );
in.putExtra(TAG_NAME, pName);
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// starting new activity and expecting some response back
startActivityForResult(in, 100);
}
});
}
// Response from Product Activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// if result code 100
if (resultCode == 100) {
// if result code 100 is received
// means user edited/deleted product
// reload this screen again
Intent intent = getIntent();
finish();
startActivity(intent);
}
}
/**
* Background Async Task to Load all product by making HTTP Request
* */
class LoadAllProducts extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(AllProductsActivity.this);
pDialog.setMessage("Loading products. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url_all_products, "GET", params);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
m_listing = json.getJSONArray(TAG_MENU_LISTING);
// looping through All Products
for (int i = 0; i < m_listing.length(); i++) {
JSONObject c = m_listing.getJSONObject(i);
// Storing each json item in variable
//String product_id = c.getString(TAG_PRODUCT_ID);
String name = c.getString(TAG_NAME);
String image_path ="http://10.0.2.2/images/" +
c.getString(TAG_IMAGE_PATH);
//String restaurant = c.getString(TAG_RESTAURANT);
imageArray.add(image_path);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
//map.put(TAG_PRODUCT_ID, product_id);
map.put(TAG_NAME, name);
//map.put(TAG_IMAGE_PATH, image_path);
//map.put(TAG_RATING, rating);
// adding HashList to ArrayList
productsList.add(map);
System.out.println(map.get(TAG_NAME));
pDialog.dismiss();
}
//System.out.println(imageArray);
} else {
// no products found
// Launch Add New product Activity
Intent i = new Intent(getApplicationContext(),
NewProductActivity.class);
// Closing all previous activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
jParser.convertInputStream(imageArray);
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
//pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
// This R.layout.List_item is the list view layout, It can be
designed according to my specs
ListAdapter adapter = new CustomListingListAdapter(
AllProductsActivity.this, productsList,
R.layout.list_item_layout, new String[] { TAG_NAME
});
setListAdapter(adapter);
}
});
}
}
public ArrayList<String> getArray(){
System.out.println(imageArray);
return imageArray;
}
}
这是我从URL获取图像的类(工作精细,可以将URL转换为BITMAP ARRAY)
public HashMap<String, Bitmap> convertInputStream(ArrayList<String> imageArray){
for(int i = 0; i<imageArray.size(); i++){
String url = imageArray.get(i);
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse httpResponse = client.execute(httpGet);
final int statusCode =
httpResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode
+ " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = httpResponse.getEntity();
if(entity != null){
inputStream = null;
inputStream = entity.getContent();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
bitmapArray.put("listing_images", bitmap);
}
if(inputStream != null){
inputStream.close();
}
entity.consumeContent();
} catch (IOException e) {
httpGet.abort();
Log.w("ImageDownloader", "Error while retrieving bitmap from " +
url);
}finally{
if(client != null){
client.close();
}
}
System.out.println(bitmapArray);
}
return null;
}
public ArrayList<HashMap<String, Bitmap>> getBitmapArray(){
listingImages.add(bitmapArray);
System.out.println(listingImages);
return listingImages;
}
}
这是我的自定义列表适配器
public class CustomListingListAdapter extends ArrayAdapter<HashMap<String, String>> {
JSONParser bitarray = new JSONParser();
private ArrayList<HashMap<String, Bitmap>> bitmapArray =
bitarray.getBitmapArray();
private ArrayList<HashMap<String, String>> data;
private Context context;
private LayoutInflater mInflater;
private int viewId;
private String[] tag;
//private static final String TAG_CONTENT = "content";
//private static final String TAG_RATING = "rating";
private static final String TAG_NAME = "name";
//private static final String TAG_RANK = "rank";
public CustomListingListAdapter(Context c,
ArrayList<HashMap<String, String>> data,
int viewId, String[] tag) {
super( c, viewId, data);
this.context = c;
this.data= data;
this.viewId = viewId ;
}
@Override
public int getCount() {
return data.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
Holder holder;
if (convertView == null) {
// Inflate the view since it does not exist
if (vi == null) {
mInflater = (LayoutInflater)
getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vi = mInflater.inflate(R.layout.list_item_layout, null);
}
holder = new Holder();
holder.Name = (TextView) vi.findViewById(R.id.name);
//holder.imageView = (ImageView) vi.findViewById(R.id.list_image);
vi.setTag(holder);
}else {
holder = (Holder) vi.getTag();
}
HashMap<String, String> currentData = new HashMap<String,
String>();
currentData = (HashMap<String, String>) data.get(position);
HashMap<String, Bitmap> currentImages = new HashMap<String, Bitmap>();
currentImages = bitmapArray.get(position);
if (currentData != null) {
holder.Name.setText(currentData.get(TAG_NAME));
}
if (holder.imageView != null) {
holder.imageView.setImageBitmap(currentImages.get("listing_images"));
}
return vi;
}
private static class Holder {
public ImageView imageView;
public TextView Name;
}
}
我得到的错误是:
08-17 14:50:04.649: I/System.out(840):
{listing_images=android.graphics.Bitmap@40ded1a8}
08-17 14:50:24.379: I/System.out(840):
{listing_images=android.graphics.Bitmap@40dead80}
08-17 14:50:24.629: I/System.out(840):
{listing_images=android.graphics.Bitmap@40d0fe10}
08-17 14:50:24.629: D/AndroidRuntime(840): Shutting down VM
08-17 14:50:24.629: W/dalvikvm(840): threadid=1: thread
exiting with uncaught exception (group=0x40a71930)
08-17 14:50:24.660: E/AndroidRuntime(840): FATAL
EXCEPTION: main
08-17 14:50:24.660: E/AndroidRuntime(840):
java.lang.NullPointerException
08-17 14:50:24.660: E/AndroidRuntime(840): at com.example.login.JSONParser.getBitmapArray(JSONParser.java:160)
08-17 14:50:24.660: E/AndroidRuntime(840): at com.example.login.CustomListingListAdapter.<init>(CustomListingListAdapter.java:26)
08-17 14:50:24.660: E/AndroidRuntime(840): at com.example.login.AllProductsActivity$LoadAllProducts$1.run(AllProductsActivity.java:239)
08-17 14:50:24.660: E/AndroidRuntime(840): at android.app.Activity.runOnUiThread(Activity.java:4644)
08-17 14:50:24.660: E/AndroidRuntime(840): at com.example.login.AllProductsActivity$LoadAllProducts.onPostExecute(AllProductsActivity.java:233)
08-17 14:50:24.660: E/AndroidRuntime(840): at com.example.login.AllProductsActivity$LoadAllProducts.onPostExecute(AllProductsActivity.java:1)
08-17 14:50:24.660: E/AndroidRuntime(840): at android.os.AsyncTask.finish(AsyncTask.java:631)
08-17 14:50:24.660: E/AndroidRuntime(840): at android.os.AsyncTask.access$600(AsyncTask.java:177)
08-17 14:50:24.660: E/AndroidRuntime(840): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
08-17 14:50:24.660: E/AndroidRuntime(840): at android.os.Handler.dispatchMessage(Handler.java:99)
08-17 14:50:24.660: E/AndroidRuntime(840): at android.os.Looper.loop(Looper.java:137)
08-17 14:50:24.660: E/AndroidRuntime(840): at android.app.ActivityThread.main(ActivityThread.java:5041)
08-17 14:50:24.660: E/AndroidRuntime(840): at java.lang.reflect.Method.invokeNative(Native Method)
08-17 14:50:24.660: E/AndroidRuntime(840): at java.lang.reflect.Method.invoke(Method.java:511)
08-17 14:50:24.660: E/AndroidRuntime(840): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-17 14:50:24.660: E/AndroidRuntime(840): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-17 14:50:24.660: E/AndroidRuntime(840): at dalvik.system.NativeStart.main(Native Method)
08-17 14:55:24.799: I/Process(840): Sending signal. PID: 840 SIG: 9
答案 0 :(得分:0)
好的做法是定义描述列表中某个项目的抽象。该项目可以保存图像,文本等。
onGetView上的convertView != null
,永远不会调用new
,它会在滚动列表时生成很多对象,这会触发GC工作并使你的UI冻结几秒钟。