为什么我的asynctask工作不正常?

时间:2014-04-23 18:44:33

标签: android eclipse multithreading

很抱歉格式化很奇怪;我不知道如何在这里格式化,这是我的第一个问题。

如果我直接从我的onCreate()调用方法accessDatabase(),但是一旦我尝试使用异步任务,我无法使其工作,它可以正常工作,它当前形成的应用程序只是崩溃。当我没有崩溃时,它仍然不显示accessDatabase()应该具有的信息。

任何建议表示赞赏。

package com.example.packagetrackingsystem;


import java.io.IOException;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * An activity that displays a valid package id's locations.
 * Allows for user to click a button to go into map view.
 * @author kr
 *
 */
public class PackageTextView extends Activity {

    //String url2;
    //JSONParser jsonParser = new JSONParser();
    static JSONReader jr = new JSONReader();
    static JSONReader jr2 = new JSONReader();
    static JSONReader jr3 = new JSONReader();

    String[] sArr = new String[1];

    private String jsonResult, jsonResult2, jsonResult3;

    static String locationsUrl = "http://ptsuwgb.comxa.com/ptsdbs4/get_all_locations.php";
    static String packagesUrl = "http://ptsuwgb.comxa.com/ptsdbs4/get_all_packages.php";
    static String customersUrl = "http://ptsuwgb.comxa.com/ptsdbs4/get_all_customers.php";

    final static int LOCATIONS = 1;
    final static int PACKAGES = 2;
    final static int CUSTOMERS = 3;

    private MapLocations mapLocation = new MapLocations();
    private String packageId;

    private ListView listViewLocations;
    TextView textViewTest, textViewDateOfShipment;
    Button buttonMapView;

    private ArrayList<String> locationStrings = new ArrayList<String>();
    private ArrayList<JSONObject> locationsArrayList = new ArrayList<JSONObject>();
    private ArrayList<JSONObject> packagesArrayList = new ArrayList<JSONObject>();
    private ArrayList<JSONObject> customersArrayList = new ArrayList<JSONObject>();
    //ArrayList<JSONObject> packageActivity = new ArrayList<JSONObject>();

    /**
     * Sets content view, button, and views.
     * Displays package statuses.
     * Generates a Location object for map view.
     * @param savedInstanceState
     */
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.package_text_view);

        textViewTest = (TextView)findViewById(R.id.textViewTest);
        textViewDateOfShipment = (TextView)findViewById(R.id.textViewDateOfShipment);
        listViewLocations = (ListView) findViewById(R.id.listViewLocations);
        buttonMapView = (Button)findViewById(R.id.buttonMapView);

        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            packageId = extras.getString("PACKAGE_ID");
        }
        else
            textViewTest.setText("null");


        //accessDatabase(locationsUrl, LOCATIONS, jr);
        //accessDatabase(packagesUrl, PACKAGES, jr2);
        //accessDatabase(customersUrl, CUSTOMERS, jr3);

        DisplayAsyncTask dat = new DisplayAsyncTask();
        dat.execute();
        createLocation(locationsArrayList, packagesArrayList, customersArrayList);
        //Toast.makeText(this, "Your information has been retieved.", Toast.LENGTH_LONG).show();

        buttonMapView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Class ourClass;
                try {

                    Bundle extras = new Bundle();
                    extras.putParcelable("MAP_LOCATION", mapLocation);
                    ourClass = Class.forName("com.example.packagetrackingsystem.MainMapActivity");      
                    Intent ourIntent = new Intent(PackageTextView.this, ourClass);
                    ourIntent.putExtras(extras);
                    textViewTest.setText(mapLocation.getLocation(mapLocation.getLength() - 1) + "");
                    //ourIntent.putExtra("MAP_LOCATION", mapLocation);
                    //startActivity(ourIntent);
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });
    }

    private class DisplayAsyncTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Toast.makeText(PackageTextView.this, "Your info is being retieved.", Toast.LENGTH_LONG).show();
        }

        @Override
        protected Void doInBackground(Void... params) {

            PackageTextView.this.accessDatabase(locationsUrl, LOCATIONS, jr);
            PackageTextView.this.accessDatabase(packagesUrl, PACKAGES, jr2);
            PackageTextView.this.accessDatabase(customersUrl, CUSTOMERS, jr3);
            return null;
        }

        protected void onPostExec() {
            //Toast.makeText(PackageTextView.this, "Your information has been retieved.", Toast.LENGTH_LONG).show();
        }

    }


    /**
     * Fills mapLocation with data.
     * @param locList The locations for the package.
     * @param packList The list to link the location with a customer
     * @param custList The list of customers to look through and find correct customer for a package.
     */
    private void createLocation(ArrayList<JSONObject> locList, ArrayList<JSONObject> packList, ArrayList<JSONObject> custList) {
        // we don't want to display a checked out status on map since a check in would already have been shown
        for(int i = 0; i < locList.size(); i++) {
            if(!(locList.get(i).optString("Status").equals("CHECKEDOUT")))
                mapLocation.addToArray(locList.get(i));
        }

        // getting customer id
        int custId = 0;
        for(int i = 0; i < packList.size(); i++) {
            JSONObject jObj = packList.get(i);

            if(jObj.optInt("PackageId") == Integer.parseInt(packageId)) {
                custId = jObj.optInt("CustomerId");
            }
        }

        String street = null;
        String city = null;
        String state = null;
        String zipCode = null;

        // getting address of correct customer, this represents final destination
        for(int i = 0; i < custList.size(); i++) {
            JSONObject jObj = custList.get(i);

            if(jObj.optInt("CustomerId") == custId) {
                street = jObj.optString("Street");
                city = jObj.optString("City");
                state = jObj.optString("State");
                zipCode = jObj.optString("ZipCode");
            }
        }

        String address = street + " " + city + " " + state + " " + zipCode;

        // getting latitude and longitude from address of customer
        Geocoder geoC = new Geocoder(PackageTextView.this.getApplicationContext(), Locale.getDefault());
        List<Address> addresses = null;
        try {
            addresses = geoC.getFromLocationName(address, 1);
        } catch (IOException e) {
            e.printStackTrace();
        }

        Address location = addresses.get(0);
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();

        mapLocation.setFinalDestination(latitude, longitude);
    }

    /**
     * Accesses certain parts of the database depending on parameters.
     * @param url the url of the php file
     * @param entity the table of the database to access
     * @param jReader the JSONReader to use
     */
    private void accessDatabase(String url, int entity, JSONReader jReader) {

        try {
            jsonResult = jReader.execute(new String[] { url }).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        if(entity == LOCATIONS)
            showAddressText();
        else if(entity == PACKAGES)
            getAllPackages();
        else if(entity == CUSTOMERS)
            getAllCustomers();

     }

    /**
     * Gets all customers from the Customer table in database.
     * Adds them to an ArrayList.
     */
    private void getAllCustomers() {
         try {
               JSONObject jsonResponse = new JSONObject(jsonResult);
               JSONArray jsonCustomersArray = jsonResponse.optJSONArray("Customer");

               for(int i = 0; i < jsonCustomersArray.length(); i++) {   
                   JSONObject jsonCustomer = jsonCustomersArray.getJSONObject(i);
                   customersArrayList.add(jsonCustomer);
               }
          } catch (JSONException e) {
              Toast.makeText(getApplicationContext(), "Error" + e.toString(),
              Toast.LENGTH_SHORT).show();
          }
    }

    /**
     * Gets all packages from the Package table in the database.
     * Adds them to an ArrayList.
     */
    private void getAllPackages() {
         try {
               JSONObject jsonResponse = new JSONObject(jsonResult);
               JSONArray jsonPackagesArray = jsonResponse.optJSONArray("Package");

               for(int i = 0; i < jsonPackagesArray.length(); i++) {   
                   JSONObject jsonPackage = jsonPackagesArray.getJSONObject(i);
                   packagesArrayList.add(jsonPackage);                 
               }
          } catch (JSONException e) {
              Toast.makeText(getApplicationContext(), "Error" + e.toString(),
              Toast.LENGTH_SHORT).show();
          }
    }

    /**
     * Displays the correct locations based on packageId given.
     * Fills an ArrayList with those locations.
     */
    public void showAddressText() {
        String dateTime = null;
        String status = null;

          try {
               JSONObject jsonResponse = new JSONObject(jsonResult);
               JSONArray jsonLocationsArray = jsonResponse.optJSONArray("Location");
               int currentLocationIndex = jsonLocationsArray.length() - 1;

               for(int i = 0; i < jsonLocationsArray.length(); i++) {   
                   JSONObject jsonLocation = jsonLocationsArray.getJSONObject(i);

                   if(jsonLocation.optInt("PackageId") == Integer.parseInt(packageId)) {
                       //packageActivity.add(jsonLocation);
                       locationsArrayList.add(jsonLocation);
                       String address = convertCoordsToAddress(jsonLocation);
                       dateTime = jsonLocation.optString("DateTime");
                        status = jsonLocation.optString("Status");
                       locationStrings.add(status + "\n" + address + "\n\t" + dateTime);;
                   }                   
               }

               if(locationStrings.isEmpty()) 
                   locationStrings.add("Id not valid");

          } catch (JSONException e) {
              Toast.makeText(getApplicationContext(), "Error" + e.toString(),
              Toast.LENGTH_SHORT).show();
          }

        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
                this, 
                android.R.layout.simple_list_item_1,
                locationStrings );

        listViewLocations.setAdapter(arrayAdapter); 
    }

    /**
     * Converts a JSONObject's latitude and longitude to readable address form.
     * @param jsonChildNode The JSONObject to use.
     * @return address the address generated from the JSONObject's information.
     */
    private String convertCoordsToAddress(JSONObject jsonChildNode) {
        String address = "";
        Geocoder geoC = new Geocoder(PackageTextView.this.getApplicationContext(), Locale.getDefault());
        List<Address> addresses = null;

        double latitude = jsonChildNode.optDouble("Latitude");
        double longitude = jsonChildNode.optDouble("Longitude");

        try {
            addresses = geoC.getFromLocation(latitude, longitude, 1);
        } catch (IOException e) {
            Log.e("LocationSampleActivity",
                    "IO Exception in getFromLocation()");
            e.printStackTrace();
        }

        address += "\t" + addresses.get(0).getAddressLine(0) + "\n\t";
        address += addresses.get(0).getAddressLine(1);

        return address;
    }
}

logcat的:

04-23 13:49:23.931: I/Adreno200-EGLSUB(13199): <ConfigWindowMatch:2081>: Format RGBA_8888.
04-23 13:49:23.951: D/memalloc(13199): /dev/pmem: Mapped buffer base:0x50ac3000 size:6733824 offset:6119424 fd:54
04-23 13:49:24.041: D/memalloc(13199): /dev/pmem: Mapped buffer base:0x512c3000 size:4890624 offset:4276224 fd:57
04-23 13:49:25.552: D/memalloc(13199): /dev/pmem: Mapped buffer base:0x5186d000 size:3129344 offset:2514944 fd:60
04-23 13:49:25.682: I/Adreno200-EGLSUB(13199): <ConfigWindowMatch:2081>: Format RGBA_8888.
04-23 13:49:25.692: D/memalloc(13199): /dev/pmem: Mapped buffer base:0x51c6f000 size:5505024 offset:4890624 fd:63
04-23 13:49:25.743: D/memalloc(13199): /dev/pmem: Mapped buffer base:0x521f4000 size:6119424 offset:5505024 fd:69
04-23 13:49:25.763: D/memalloc(13199): /dev/pmem: Unmapping buffer base:0x50ac3000 size:6733824 offset:6119424
04-23 13:49:25.763: D/memalloc(13199): /dev/pmem: Unmapping buffer base:0x512c3000 size:4890624 offset:4276224
04-23 13:49:25.763: D/memalloc(13199): /dev/pmem: Unmapping buffer base:0x5186d000 size:3129344 offset:2514944
04-23 13:49:26.203: D/memalloc(13199): /dev/pmem: Mapped buffer base:0x50ac3000 size:3129344 offset:2514944 fd:54
04-23 13:49:28.735: W/dalvikvm(13199): threadid=1: thread exiting with uncaught exception (group=0x40a6e1f8)
04-23 13:49:28.745: E/AndroidRuntime(13199): FATAL EXCEPTION: main
04-23 13:49:28.745: E/AndroidRuntime(13199): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.packagetrackingsystem/com.example.packagetrackingsystem.PackageTextView}: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.app.ActivityThread.access$600(ActivityThread.java:123)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.os.Looper.loop(Looper.java:137)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.app.ActivityThread.main(ActivityThread.java:4424)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at java.lang.reflect.Method.invokeNative(Native Method)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at java.lang.reflect.Method.invoke(Method.java:511)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:812)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:579)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at dalvik.system.NativeStart.main(Native Method)
04-23 13:49:28.745: E/AndroidRuntime(13199): Caused by: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
04-23 13:49:28.745: E/AndroidRuntime(13199):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at java.util.ArrayList.get(ArrayList.java:304)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at com.example.packagetrackingsystem.PackageTextView.createLocation(PackageTextView.java:199)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at com.example.packagetrackingsystem.PackageTextView.onCreate(PackageTextView.java:98)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.app.Activity.performCreate(Activity.java:4465)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
04-23 13:49:28.745: E/AndroidRuntime(13199):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
04-23 13:49:28.745: E/AndroidRuntime(13199):    ... 11 more

不确定如何获得......还有11个。

1 个答案:

答案 0 :(得分:3)

当您致电dat.execute()时,它不会立即运行。

首先,onPreExecute()函数将在主线程上执行。所以它会在你的onCreate()活动之后执行。

然后,doInBackground()函数将在另一个线程中运行。完成后,onPostExecute()将在主线程上执行。

因此,您不应在createLocation()之后致电dat.execute()。那时,还没有提取数据。您应该在onPostExecute()

中执行此操作

顺便说一下,它是onPostExecute(),而不是onPostExec()