簡體   English   中英

在AsyncTask之后自定義適配器更新

[英]Custom adapter update after AsyncTask

好吧,我在這里真的很困惑。 這是正在發生的事情的一些摘要。

  1. 我通過GPD獲取用戶位置
  2. 在第一個IF語句中,我收集了要輸入到適配器中的“ opzioni”和“ images”,但是我還需要第三個數組,其數據只能在腳本的后面收集。

  3. 我在數據庫中收集元素的坐標

  4. 運行一個AsyncTask,返回用戶和數據庫元素之間的距離。
  5. 將DISTANCE值放入距離Array內,循環進行五次。

現在我遇到的問題是,在調用適配器之前,“ 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。

第一個活動收到第二個結果,我將在需要的地方做。 希望對您有幫助。

我不知道您是否可以解決此問題。 無論如何,今天我找到了一種執行所需操作的方法。

  1. 首先,您必須在AsyncTask中創建一個構造器方法,以將Activity作為參數接收。 在此構造函數中,您將使用接收到的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);
        }
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM