2013-10-15 55 views
0

好吧,我在這裏變得非常困惑。 以下是發生了什麼事情的小結。AsyncTask後自定義適配器更新

  1. 我通過GPD
  2. 在第一種獲取用戶位置IF語句我收集「opzioni」和「圖像」,我想喂到我的適配器,但我還需要第三個數組,其數據I只能在以後的腳本中收集。

  3. 我收集數據庫

  4. 運行,返回用戶和數據庫元素之間的距離的的AsyncTask內的元素的座標。
  5. DISTANCE值放在距離陣列和循環進行五次。

現在我的問題是在調用適配器之前收集「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) 

有沒有人有同樣的問題? 我真的很掙扎

謝謝

回答

0

目前你有以下問題ParserTask類:

忘記調用明確或添加元素之前初始化test列表列出

2.使用adapter的未初始化實例,因爲您正在內創建具有相同名稱的Adapter的另一個實例。

adapter = new NewAdapter(this, opzioni, images, distance); //<< 
l.setAdapter(adapter); 
l.setOnItemClickListener(this); 
+0

我不知道我得到這個。我是否必須在ParserTask中初始化相同的適配器? – Francesco

0

@邁克爾柯里昂,我前幾天也遇到類似的問題。問題是:當你調用一個AsyncTask時,你的主代碼仍在運行。

爲了「解決」這個問題,我通常使用兩個活動和一個AsyncTask類。

所以,我的第一個活動調用startActivityForResult()。

第二個活動發送ProgressDialog和其他數據到我的AsyncTask。然後,在執行doInBackground()後,調用onPostExecute(),關閉ProgressDialog並將第二個Activity的RESULT設置爲「OK」或「CANCELED」。在這兩種情況下,我關閉ProgressDialog並完成()第二個Activity。

第一個Activity收到第二個結果,我會在需要的地方進行。我希望它能幫助你。

+0

我明白了!我想看看我能否找到一種更優雅的方式來解決這個問題,否則我會試試這個。謝謝 – Francesco

0

我不知道你是否可以解決這個問題。無論如何,今天我找到了一種方法去做你想做的事。

  1. 首先,您必須在接收Activity作爲參數的AsyncTask中創建構造函數方法。在這個構造函數中,您將使用接收到的Activity來設置上下文。
  2. 在將調用AsyncTask的Activity中,您將創建一個公共方法來更新視圖中的數據。
  3. AsyncTask類需要有一個將調用AsyncTask的所有活動的特定實例(但不必將它們全部初始化);
  4. 在doInBackground()方法中,您必須使用執行後將使用的數據初始化Object;
  5. 在onPostExecute()方法中,您必須驗證哪個活動稱爲任務,並將新數據設置爲您的視圖。

參見:

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); 
     } 
    } 

}