Async Task Произошла ошибка при выполнении doInBackground () - PullRequest
12 голосов
/ 17 ноября 2011

Из моего предыдущего вопроса

Я получил исключение NullPointor.Итак, я сделал некоторые изменения в своем коде, и теперь отображается индикатор выполнения, но я получаю следующие ошибки:

11-17 23:39:51.373: ERROR/AndroidRuntime(495): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
11-17 23:39:51.373: ERROR/AndroidRuntime(495): java.lang.RuntimeException: An error occured while executing doInBackground()
11-17 23:39:51.373: ERROR/AndroidRuntime(495):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
11-17 23:39:51.373: ERROR/AndroidRuntime(495):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-17 23:39:51.373: ERROR/AndroidRuntime(495):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-17 23:39:51.373: ERROR/AndroidRuntime(495):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-17 23:39:51.373: ERROR/AndroidRuntime(495):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-17 23:39:51.373: ERROR/AndroidRuntime(495):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
11-17 23:39:51.373: ERROR/AndroidRuntime(495):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
11-17 23:39:51.373: ERROR/AndroidRuntime(495):     at java.lang.Thread.run(Thread.java:1096)
11-17 23:39:51.373: ERROR/AndroidRuntime(495): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

Код - это ...

 public class JsonExampleActivity extends ListActivity {
/** Called when the activity is first created. */
ProgressDialog mDialog;

final String TAG="a.c.b";
JSONFunction JSONfunction;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.listplaceholder);

   new JSONPasingShowList().execute();
}

public void updateWithNewLocation(Location location2) {
    if(location2!=null) {
          double geoLat = location2.getLatitude();

            double geoLng = location2.getLongitude();

    }

}

class JSONPasingShowList extends AsyncTask<String, Integer,ArrayList<HashMap<String,String>>>
{


  @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mDialog = new ProgressDialog(JsonExampleActivity.this);
        mDialog.setCancelable(true);
        mDialog.setMessage("Loading...");
        mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mDialog.setProgress(0);
        mDialog.show();
    }


@Override
protected ArrayList<HashMap<String,String>> doInBackground(String... params) {

    double latitude[]=new double[20];
    double longitude[]=new double[20];
    String reference[]=new String[20];
    double distance[]=new double[20];
    LocationManager locationManager;
    String context=Context.LOCATION_SERVICE;
    locationManager=(LocationManager)getSystemService(context);
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    String provider = locationManager.getBestProvider(criteria, true);
    Location location = locationManager.getLastKnownLocation(provider);

    final LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
        updateWithNewLocation(location);
        }
        public void onProviderDisabled(String provider){
        updateWithNewLocation(null);
        }
        public void onProviderEnabled(String provider){ }
        public void onStatusChanged(String provider, int status,
        Bundle extras){ }
        };

    updateWithNewLocation(location);
    locationManager.requestLocationUpdates(provider, 2000, 10,
            locationListener);


    double geoLat = location.getLatitude();
    Log.v(TAG, "hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"+geoLat);
    double geoLng = location.getLongitude();
    Log.v(TAG, "hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"+geoLng);
    ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();


    JSONObject  json=JSONFunction.getJSONfromURL("https://maps.googleapis.com/maps/api/place/search/json?location=37.422006,-122.084095&radius=1000&types=doctor&sensor=true&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

    try{
        JSONArray  JArray = json.getJSONArray("results");
           Log.v(TAG, "getting results");
        for(int i=0;i<JArray.length();i++){                     
            HashMap<String, String> map = new HashMap<String, String>();    
            JSONObject e = JArray.getJSONObject(i);
            JSONObject location1=e.getJSONObject("geometry").getJSONObject("location");
            latitude[i]=location1.getDouble("lat");
            longitude[i]=location1.getDouble("lng");
            reference[i]=e.getString("reference");
            Log.v(TAG, reference[i]);
            distance[i]=GetLatAndLng.gps2m(geoLat, geoLng,latitude[i] ,longitude[i]); 

            map.put("id",  String.valueOf(i));
            map.put("name", "" + e.getString("name"));
            map.put("vicinity", "Address " +  e.getString("vicinity")+" "+"Disance:"+distance[i]);

            mylist.add(map);                        
        }   }catch(JSONException e)        {
             Log.e("log_tag", "Error parsing data "+e.toString());
        }
        final Intent intent=new Intent(JsonExampleActivity.this ,GetLatAndLng.class);
        Bundle b=new Bundle();
        b.putStringArray("key", reference);
        intent.putExtras(b);   
    return mylist;
}

 @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
    mDialog.dismiss();
     ListAdapter adapter = new SimpleAdapter(JsonExampleActivity.this, result , R.layout.listview, 
             new String[] { "name", "vicinity", }, 
             new int[] { R.id.item_title, R.id.item_subtitle });

 setListAdapter(adapter);
 mDialog.dismiss();
 final ListView lv = getListView();
 lv.setTextFilterEnabled(true); 
 lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {          
    @SuppressWarnings("unchecked")
        HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);                   
   Toast.makeText(JsonExampleActivity.this, "ID '" + o.get("id") + "' was clicked.", Toast.LENGTH_SHORT).show();
  final Intent intent=new Intent(JsonExampleActivity.this ,GetLatAndLng.class);
   intent.putExtra("clickedid",position);
    startActivity(intent);
    }
});
}
public class MySimpleAdapter extends SimpleAdapter {
     public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
        super(context, data, resource, from, to);
        // TODO Auto-generated constructor stub
}
}
}
}

Что происходит не так?Заранее спасибо !!!

Ответы [ 3 ]

16 голосов
/ 17 ноября 2011
Can't create handler inside thread that has not called Looper.prepare()

Вы обращаетесь к чему-то в потоке пользовательского интерфейса из doInBackground. И это не разрешено.

* редактировать: я видел все. Для меня то, что выглядит необычно, это такие строки:

updateWithNewLocation(location); // What does this do? Could you tell me?
locationManager.requestLocationUpdates(provider, 2000, 10,
        locationListener); // I don't think this is it

Попробуйте переместить все эти данные об обновлении местоположения в onProgressUpdate. Я слепой здесь, так как не вижу ваш код, но я догадываюсь что-то делает с пользовательским интерфейсом. Попробуйте это:

@Override
protected void onProgressUpdate(Location... locations) {
    super.onProgressUpdate(values);
    updateWithNewLocation(location);
}

Но, как я уже сказал, я не уверен, поскольку не могу знать, что делает updateWithNewLocation, если вы не разместите здесь этот код.

6 голосов
/ 17 ноября 2011

Именно поэтому важно начать понимать некоторые основы, связанные с многопоточностью, вместо того, чтобы просто сказать «AsyncTask» для всего, что кажется удаленно связанным с многопоточностью в Android.Многопоточность может быть сложной, и вам нужно все обдумать.

Я подозреваю, что это то, что происходит: у вас есть AsyncTask, который, помимо прочего, получает местоположение ... асинхронно.Это означает, что вы начинаете в главном потоке, вы выполняете doInBackground в другом потоке неявно (поток AsyncTask), а затем вызываете любой поток, выполняющий определение местоположения.Затем ваш поток AsyncTask продолжает работу, завершая всю эту работу, связанную с JSON, в doInBackground, возможно, заканчивая.Поток AsyncTask, вероятно, завершается. Затем вы получаете блокировку местоположения, и предоставленный вами прослушиватель вызывается обратно, за исключением того, что теперь AsyncTask уже завершен, и его поток больше не действителен.

Просто на основеПосмотрите на ваш код Я подозреваю, что вы хотите позвонить по API Карт Google после того, как узнаете свое местоположение, верно?Если это так, вызовите свой код «получить местоположение» синхронно.В обратном вызове вы можете добавить код для запуска AsyncTask, который теперь выполняет только вызов и обработку Google Maps API.

5 голосов
/ 17 ноября 2011

Вы делаете кучу вещей в вашем doInBackground(), которые вам не нужно делать там. Делайте в методе doInBackground() только то, что может вызвать заикание в потоке пользовательского интерфейса. Другими словами, весь код, который не имеет непосредственного отношения к вашему сетевому взаимодействию, должен быть удален из вашего doInBackground() метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...