AsyncTask之后的自定义适配器更新

时间:2013-10-15 16:51:24

标签: android android-asynctask android-adapter

好吧,我在这里真的很困惑。 以下是对正在发生的事情的一点总结。

  1. 我通过GPD获取用户位置
  2. 在第一个IF语句中,我收集了“opzioni”和“images”,我想将其提供给我的适配器,但我还需要第三个数组,我的数据只能在稍后的脚本中收集。

  3. 我收集数据库中元素的坐标

  4. 运行AsyncTask,返回用户和数据库元素之间的DISTANCE。
  5. DISTANCE值放在距离数组内,循环进行五次。
  6. 现在的问题是,在调用适配器之前收集“opzioni”和“images”,而我只能在每次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)
    

    有没有人有同样的问题? 我真的很挣扎

    谢谢

3 个答案:

答案 0 :(得分:0)

目前您在ParserTask课程中遇到以下问题:

1。在调用clear或添加元素到列表之前忘记初始化test列表

2。使用非初始化的adapter实例,因为您要在onCreate内创建另一个同名的Adapter实例。

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

答案 1 :(得分:0)

@Michael Corleone,我几天前遇到过类似的问题。问题是:当你调用AsyncTask时,你的主代码仍在运行。

为了“解决”这个问题,我通常使用两个活动和一个AsyncTask类。

因此,我的第一个活动调用startActivityForResult()。

第二个活动将ProgressDialog和其他数据发送到我的AsyncTask。然后,在doInBackground()执行后调用onPostExecute(),我关闭ProgressDialog并将第二个Activity的RESULT设置为“OK”或“CANCELLED”。在这两种情况下,我都会关闭ProgressDialog并完成()第二个Activity。

第一个Activity收到第二个结果,我随时随地都会这样做。我希望它可以帮助你。

答案 2 :(得分:0)

我不知道你是否可以解决这个问题。无论如何,今天我找到了一种方法来做你想做的事。

  1. 首先,您必须在AsyncTask中创建一个构造函数方法,该方法接收一个Activity作为参数。在此构造函数中,您将使用收到的Activity设置上下文。
  2. 在将调用AsyncTask的Activity中,您可以创建一个公共方法来更新视图中的数据。
  3. AsyncTask类需要具有调用AsyncTask的所有活动的特定实例(但您不必将它们全部初始化);
  4. 在doInBackground()方法中,您必须使用执行后将使用的数据初始化Object;
  5. 在onPostExecute()方法中,您必须验证哪个活动称为任务,并将新数据设置为您的视图。
  6. 请参阅:

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