简而言之。 我有一个asynctask,JSONReadTask请求&电台节目主持人名单。 从此列表中获取图像引用并将其传递给另一个Asyntask,ImageRetrival。
在将图像下载到列表视图时,我很难使用android的异步。
我最初在JSONReadTask的末尾有ListView.setAdapter()的适配器设置,所以一旦所有图像都被重新检索,就可以填充列表。但是当为listview设置适配器时,我不断获得适配器数据源的NullPointerException。
我需要什么,无法理解的是如何将适配器设置为列表视图,然后以某种方式使用notifyDataSetChanged()来更新列表视图,因为每个imageRetrival PostExecutes。
public class Presenters extends Activity {
private String jsonResult;
private String url = "http://www.example.co.uk/Radio/api.php?q=Presenters";
public List<HashMap<String, Bitmap>> ImageList;
private ListView listView;
private ExtendedSimpleAdapter exad;
//private Bitmap[] images;
//private int counter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_presenters);
// Show the Up button in the action bar.
setupActionBar();
//counter = 0;
listView = (ListView) findViewById(R.id.listViewPres);
accessWebService();
}
/**
* Set up the {@link android.app.ActionBar}, if the API is available.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.presenters, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
private class ImageRetrival extends AsyncTask<String, Void, Bitmap> {
private Bitmap btmp;
String id;
private String ImageUrl = "http://www.example.co.uk/RPUser/"; //Image Directory
// ///////////
// GET IMAGE//
// ///////////
protected Bitmap doInBackground(String... params) {
// download image to bitmap
try {
Log.d("URLparam", params[0]);
String u = ImageUrl + params[0];
URL url = new URL(u);
Log.d("URL:", "" + url);
// split arguments
// if(overView request)->continue;
// if(SpecificRequest)->explode(url, 'i')-> id;
/*
* if(url.toString().contains("q=") &&
* url.toString().contains("i=")){ String[] urlArray =
* url.toString().split("i=", 2); id = urlArray[1];
* Log.d("Url.Split>id", ""+id); }
*/
id = url.toString();
InputStream stream;
BufferedInputStream bis;
URLConnection ConUrl = url.openConnection();
HttpURLConnection htpcon = (HttpURLConnection) ConUrl;
htpcon.setRequestMethod("GET");
htpcon.setDoInput(true);
htpcon.connect();
if (htpcon.getResponseCode() != HttpURLConnection.HTTP_OK) {
Log.d("HTTP-ERROR", "" + htpcon.getResponseCode());
}
stream = htpcon.getInputStream();
bis = new BufferedInputStream(stream);
Log.d("Stream" + url, "" + stream);
btmp = BitmapFactory.decodeStream(bis);
Log.d("Bitmap-Code", "" + btmp);
stream.close();
} catch (IOException e) {
Log.d("Catch", "Issue Here");
e.printStackTrace();
}
return btmp;
}
protected void onPostExecute(Bitmap result) {
HashMap<String, Bitmap> table = new HashMap<String, Bitmap>();
table.put("Image", result);
Log.d("OnPost", ""+result);
ImageList.add(table); //Line 154 which returns NullPointer
exad = new ExtendedSimpleAdapter(Presenters.this,
ImageList, R.layout.listview_item_row_presenters, new String[]
{"Image", "Name", "About"}, new int[] {R.id.imgIcon, R.id.txtTitle,
R.id.txtAbout});
Log.d("PostExecute", "" + result);
listView.setAdapter(exad);
}
}
//
// Start JSON CODE
//
private class JsonReadTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
Log.d("JSON", "" + params[0]);
try {
HttpResponse responce = httpclient.execute(httppost);
jsonResult = inputStreamToString(
responce.getEntity().getContent()).toString();
Log.d("JSON", "" + jsonResult);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
}
catch (IOException e) {
// e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error..." + e.toString(), Toast.LENGTH_LONG).show();
}
return answer;
}
@Override
protected void onPostExecute(String result) {
ListDrwaer();
}
} // end Async Task extension
public void accessWebService() {
JsonReadTask task = new JsonReadTask();
// passes values for the urls string array
task.execute(new String[] { url });
}
// build hash set for list view
public void ListDrwaer() {
List<HashMap<String, String>> presenterlist = new ArrayList<HashMap<String, String>>();
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.getJSONArray("Presenters");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String name = jsonChildNode.getString("FirstName");
String lastName = jsonChildNode.getString("LastName");
String fullName = name + " " + lastName;
String about = jsonChildNode.getString("About");
String image = jsonChildNode.getString("Image");
ImageRetrival getImage = new ImageRetrival();
getImage.execute(image);
Log.d("Progress", "Got Image " + image);
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("Name", fullName);
hm.put("About", about);
hm.put("Image", image);
presenterlist.add(hm);
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(),
"Error - JSON Retrival - HashMap" + e.toString(),
Toast.LENGTH_SHORT).show();
}
/*SimpleAdapter simpleAdapter = new SimpleAdapter(this, presenterlist,
R.layout.listview_item_row_presenters, new String[] { "Image",
"Name", "About" }, new int[] { R.id.imgIcon,
R.id.txtTitle, R.id.txtAbout });*/
if(ImageList == null){
Log.d("Report", "ImageListNULL");
}
else{
Log.d("Report", ""+ImageList);
}
listView.setAdapter(exad);//Currently throws nullPointerException of HashMap<String, Bitmap>
//listView.getAdapter().notifyDataSetChanged();//want to know how to utilise this
}
//
// End JSON Code
}
扩展适配器:
public class ExtendedSimpleAdapter extends SimpleAdapter{
List<HashMap<String, Bitmap>> map;
String[] from;
int layout;
int[] to;
Context context;
LayoutInflater mInflater;
public ExtendedSimpleAdapter(Context context, List<HashMap<String, Bitmap>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
layout = resource;
map = data;
this.from = from;
this.to = to;
this.context = context;
}
@Override
public int getCount(){
return map.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return this.createViewFromResource(position, convertView, parent, layout);
}
private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {
View v;
if (convertView == null) {
v = mInflater.inflate(resource, parent, false);
} else {
v = convertView;
}
this.bindView(position, v);
return v;
}
private void bindView(int position, View view) {
final Map dataSet = map.get(position);
if (dataSet == null) {
return;
}
final ViewBinder binder = super.getViewBinder();
final int count = to.length;
for (int i = 0; i < count; i++) {
final View v = view.findViewById(to[i]);
if (v != null) {
final Object data = dataSet.get(from[i]);
String text = data == null ? "" : data.toString();
if (text == null) {
text = "";
}
boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
if (!bound) {
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else {
throw new IllegalStateException(v.getClass().getName() +
" should be bound to a Boolean, not a " +
(data == null ? "<unknown type>" : data.getClass()));
}
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else if (data instanceof Bitmap){
setViewImage((ImageView) v, (Bitmap)data);
} else {
setViewImage((ImageView) v, text);
}
} else {
throw new IllegalStateException(v.getClass().getName() + " is not a " +
" view that can be bounds by this SimpleAdapter");
}
}
}
}
}
private void setViewImage(ImageView v, Bitmap bmp){
v.setImageBitmap(bmp);
}
}
提前谢谢
LogCat输出:
05-27 13:56:19.010: E/AndroidRuntime(2861): FATAL EXCEPTION: main
05-27 13:56:19.010: E/AndroidRuntime(2861): java.lang.NullPointerException
05-27 13:56:19.010: E/AndroidRuntime(2861): at com.example.dev_app001.Presenters$ImageRetrival.onPostExecute(Presenters.java:154)
05-27 13:56:19.010: E/AndroidRuntime(2861): at com.example.dev_app001.Presenters$ImageRetrival.onPostExecute(Presenters.java:1)
05-27 13:56:19.010: E/AndroidRuntime(2861): at android.os.AsyncTask.finish(AsyncTask.java:631)
05-27 13:56:19.010: E/AndroidRuntime(2861): at android.os.AsyncTask.access$600(AsyncTask.java:177)
05-27 13:56:19.010: E/AndroidRuntime(2861): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
05-27 13:56:19.010: E/AndroidRuntime(2861): at android.os.Handler.dispatchMessage(Handler.java:99)
05-27 13:56:19.010: E/AndroidRuntime(2861): at android.os.Looper.loop(Looper.java:213)
05-27 13:56:19.010: E/AndroidRuntime(2861): at android.app.ActivityThread.main(ActivityThread.java:5225)
05-27 13:56:19.010: E/AndroidRuntime(2861): at java.lang.reflect.Method.invokeNative(Native Method)
05-27 13:56:19.010: E/AndroidRuntime(2861): at java.lang.reflect.Method.invoke(Method.java:525)
05-27 13:56:19.010: E/AndroidRuntime(2861): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
05-27 13:56:19.010: E/AndroidRuntime(2861): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
05-27 13:56:19.010: E/AndroidRuntime(2861): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:0)
您有2个任务JsonReadTask
和ImageRetrival
首先运行JsonReadTask
,然后onPostExecute
运行ImageRetrival
问题是您只能在exad
之后实例化ImageRetrival
。
因此,listView.setAdapter(exad);
未完成时调用ImageRetrival
会产生问题,因为任务是异步运行的。
我想从listView.setAdapter(exad);
移除JsonReadTask
,因为您已经ImageRetrival
完成执行后调用它。
你应该避免使用类范围的变量,它们可能导致错误和这样的空指针。
尽量保持私密性。