[英]Custom adapter update after AsyncTask
好吧,我在這里真的很困惑。 這是正在發生的事情的一些摘要。
在第一個IF語句中,我收集了要輸入到適配器中的“ opzioni”和“ images”,但是我還需要第三個數組,其數據只能在腳本的后面收集。
我在數據庫中收集元素的坐標
現在我遇到的問題是,在調用適配器之前,“ opzioni”和“圖像”都被收集了,而我只能在每個AsyncTask之后訪問距離數據。
我無法更新ListView。
這是來源
package com.example.myapp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
//import com.example.nevianoapp.NevianoMapsV2.DownloadTask;
//import com.example.nevianoapp.NevianoMapsV2.ParserTask;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PolylineOptions;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class CategoryMenu extends Activity implements AdapterView.OnItemClickListener, LocationListener {
ListView l;
String[] opzioni;
int[] images;
String[] distance;
String category;
LatLng myPos;
LatLng dest;
String distanceAsync;
int nextIndex = 0;
NewAdapter adapter;
List<List<HashMap<String, String>>> test;
DatabaseHandler db = new DatabaseHandler(this);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category_menu_layout);
// Getting LocationManager object from System Service LOCATION_SERVICE
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location From GPS
Location location = locationManager.getLastKnownLocation(provider);
myPos = new LatLng(location.getLatitude(), location.getLongitude());
Toast.makeText(this, String.valueOf(location.getLatitude())+ " " + String.valueOf(location.getLongitude()), Toast.LENGTH_SHORT).show();
//for(int x = 1; x < 6; x = x+1) {
if(getIntent().getIntExtra("str1", 0) == 0){
opzioni = new String[5];
images = new int[5];
distance = new String[5];
for (int x = 0; x < 5; x = x+1){
opzioni[x] = db.getCultura(x+1, "cultura").getName();
images[x] = (R.drawable.cultura);
dest = new LatLng(db.getCultura(x+1, "cultura").getCoordLat(), db.getCultura(x+1, "cultura").getCoordLong());
String url = getDirectionsUrl(myPos, dest);
DownloadTask downloadTask = new DownloadTask();
downloadTask.execute(url);
}
}
if(getIntent().getIntExtra("str1", 0) == 1){
opzioni = new String[13];
images = new int[13];
for (int x = 0; x < 13; x = x+1){
opzioni[x] = db.getCultura(x+1, "ristoranti").getName();
images[x] = (R.drawable.ristoranti);
}
}
if(getIntent().getIntExtra("str1", 0) == 2){
opzioni = new String[17];
images = new int[17];
for (int x = 0; x < 17; x = x+1){
opzioni[x] = db.getCultura(x+1, "alberghi").getName();
images[x] = (R.drawable.itinerari);
}
}
l=(ListView) findViewById(R.id.listView2);
NewAdapter adapter = new NewAdapter(this, opzioni, images, distance);
l.setAdapter(adapter);
l.setOnItemClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.category_menu, menu);
return true;
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Intent i = new Intent(this, informazioni.class);
category = getIntent().getStringExtra("category");
i.putExtra("str1", arg2);
i.putExtra("category", category);
Toast.makeText(this, "hey " + arg2, Toast.LENGTH_SHORT).show();// TODO Auto-generated method stub
startActivity(i);
}
private String getDirectionsUrl(LatLng origin,LatLng dest){
// Origin of route
String str_origin = "origin="+origin.latitude+","+origin.longitude;
// Destination of route
String str_dest = "destination="+dest.latitude+","+dest.longitude;
// Sensor enabled
String sensor = "sensor=false";
// Building the parameters to the web service
String parameters = str_origin+"&"+str_dest+"&"+sensor;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;
return url;
}
/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException{
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try{
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while( ( line = br.readLine()) != null){
sb.append(line);
}
data = sb.toString();
br.close();
}catch(Exception e){
Log.d("Exception while downloading url", e.toString());
}finally{
iStream.close();
urlConnection.disconnect();
}
return data;
}
/** A class to download data from Google Directions URL */
private class DownloadTask extends AsyncTask<String, Void, String>{
// Downloading data in non-ui thread
@Override
protected String doInBackground(String... url) {
// For storing data from web service
String data = "";
try{
// Fetching the data from web service
data = downloadUrl(url[0]);
}catch(Exception e){
Log.d("Background Task",e.toString());
}
return data;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
ParserTask parserTask = new ParserTask();
// Invokes the thread for parsing the JSON data
parserTask.execute(result);
}
// Executes in UI thread, after the execution of
// doInBackground()
}
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{
// Parsing the data in non-ui thread
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try{
jObject = new JSONObject(jsonData[0]);
DirectionsJSONParser parser = new DirectionsJSONParser();
// Starts parsing data
routes = parser.parse(jObject);
}catch(Exception e){
e.printStackTrace();
}
return routes;
}
// Executes in UI thread, after the parsing process
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
List<HashMap<String, String>> path = result.get(0);
HashMap<String, String> point = path.get(0);
distanceAsync = point.get("distance");
distance[nextIndex] = distanceAsync;
++nextIndex;
test.clear();
test.addAll(result);
adapter.notifyDataSetChanged();
}
}
class NewAdapter extends ArrayAdapter<String>{
Context context;
int[] images;
String[] title;
String[] subTitle;
NewAdapter(Context c, String[] opzioni, int[] imgs, String[] distanza){
super(c, R.layout.single_row, R.id.descrizione, opzioni);
this.context = c;
this.images = imgs;
this.title = opzioni;
this.subTitle = distanza;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.single_row, parent, false);
ImageView myImage = (ImageView) row.findViewById(R.id.imageView);
TextView myOptions = (TextView) row.findViewById(R.id.descrizione);
TextView mySubTitle = (TextView) row.findViewById(R.id.subTitle);
myImage.setImageResource(images[position]);
myOptions.setText(title[position]);
mySubTitle.setText(subTitle[position]);
return row;
}
}
@Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
}
}
這是日志
10-15 17:40:47.677: E/AndroidRuntime(5237): FATAL EXCEPTION: main
10-15 17:40:47.677: E/AndroidRuntime(5237): java.lang.NullPointerException
10-15 17:40:47.677: E/AndroidRuntime(5237): at com.example.nevianoapp.CategoryMenu$ParserTask.onPostExecute(CategoryMenu.java:298)
10-15 17:40:47.677: E/AndroidRuntime(5237): at com.example.nevianoapp.CategoryMenu$ParserTask.onPostExecute(CategoryMenu.java:1)
10-15 17:40:47.677: E/AndroidRuntime(5237): at android.os.AsyncTask.finish(AsyncTask.java:631)
10-15 17:40:47.677: E/AndroidRuntime(5237): at android.os.AsyncTask.access$600(AsyncTask.java:177)
10-15 17:40:47.677: E/AndroidRuntime(5237): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
10-15 17:40:47.677: E/AndroidRuntime(5237): at android.os.Handler.dispatchMessage(Handler.java:99)
10-15 17:40:47.677: E/AndroidRuntime(5237): at android.os.Looper.loop(Looper.java:137)
10-15 17:40:47.677: E/AndroidRuntime(5237): at android.app.ActivityThread.main(ActivityThread.java:5103)
10-15 17:40:47.677: E/AndroidRuntime(5237): at java.lang.reflect.Method.invokeNative(Native Method)
10-15 17:40:47.677: E/AndroidRuntime(5237): at java.lang.reflect.Method.invoke(Method.java:525)
10-15 17:40:47.677: E/AndroidRuntime(5237): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
10-15 17:40:47.677: E/AndroidRuntime(5237): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-15 17:40:47.677: E/AndroidRuntime(5237): at dalvik.system.NativeStart.main(Native Method)
有人有同樣的問題嗎? 我真的很掙扎
謝謝
當前, ParserTask
類中存在以下問題:
1.在調用clear或在列表中添加元素之前,忘記初始化test
列表
2.使用非初始化的adapter
實例,因為要在onCreate
內創建另一個具有相同名稱的Adapter實例。
adapter = new NewAdapter(this, opzioni, images, distance); //<<
l.setAdapter(adapter);
l.setOnItemClickListener(this);
@Michael Corleone,幾天前我遇到了類似的問題。 問題是:當您調用AsyncTask時,您的主要代碼仍在運行。
為了“解決”這個問題,我通常使用兩個活動和一個AsyncTask類。
因此,我的第一個活動稱為startActivityForResult()。
第二個活動將ProgressDialog和其他數據發送到我的AsyncTask。 然后,在執行doInBackground()之后,調用onPostExecute(),然后關閉ProgressDialog並將第二個Activity的RESULT設置為“ OK”或“ CANCELED”。 在這兩種情況下,我都關閉了ProgressDialog並完成了第二個Activity。
第一個活動收到第二個結果,我將在需要的地方做。 希望對您有幫助。
我不知道您是否可以解決此問題。 無論如何,今天我找到了一種執行所需操作的方法。
看到:
public class AnyActivity extends Activity {
TextView txView;
//onCreate...
//onPause...
//onResume...
public updateData(Object object) {
//update the data in the UI
}
}
public class WSCallSoap extends AsyncTask<Object, Integer, Boolean> {
AnyActivity anyActivity;
Activity activity;
DataModelClass dmc;
private ProgressDialog dialog = null;
public WSCallSoap (Activity activity){
this.activity = activity;
Context context = activity;
dialog = new ProgressDialog(context);
}
public void onPreExecute(){
this.dialog.setMessage("Sending");
this.dialog.show();
}
public boolean doInBackground(Object... params){
dmc = ... //initialize the object and do wherever you need
}
public void onPostExecute(boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (activity.class == AnyActivity.class) {
anyActivity.updateData(dmc);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.