Ответ 1
Вы не можете выполнить AsyncTask
из фонового потока. См. Раздел "Правила Threading" документация AsyncTask
.
Я разрабатываю простое приложение с использованием API Google Maps V2 только для того, чтобы получить основы, и я столкнулся с этой ошибкой:
09-09 21:21:41.154: E/AndroidRuntime(3796): FATAL EXCEPTION: Thread-441
09-09 21:21:41.154: E/AndroidRuntime(3796): java.lang.ExceptionInInitializerError
09-09 21:21:41.154: E/AndroidRuntime(3796): at cz.vongrad.dataSourceLayer.DataMapper.loadLocation(DataMapper.java:111)
09-09 21:21:41.154: E/AndroidRuntime(3796): at cz.vongrad.dataSourceLayer.DBFacade.loadLocations(DBFacade.java:32)
09-09 21:21:41.154: E/AndroidRuntime(3796): at cz.vongrad.domainLayer.Controller.loadLocations(Controller.java:94)
09-09 21:21:41.154: E/AndroidRuntime(3796): at cz.vongrad.locator.MapActivity$1.run(MapActivity.java:199)
09-09 21:21:41.154: E/AndroidRuntime(3796): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-09 21:21:41.154: E/AndroidRuntime(3796): at android.os.Handler.<init>(Handler.java:121)
09-09 21:21:41.154: E/AndroidRuntime(3796): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:607)
09-09 21:21:41.154: E/AndroidRuntime(3796): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:607)
09-09 21:21:41.154: E/AndroidRuntime(3796): at android.os.AsyncTask.<clinit>(AsyncTask.java:190)
09-09 21:21:41.154: E/AndroidRuntime(3796): ... 4 more
09-09 21:21:41.164: E/EmbeddedLogger(239): App crashed!
DataMapper:
class LoadLocations extends AsyncTask<String, Void, ArrayList<Friend>>{
private JSONObject jSONObject;
@Override
protected ArrayList<Friend> doInBackground(String... args) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("user_name", args[1]));
jSONObject = jSONParser.makeHttpRequest(args[0], "POST", params);
Log.d(TAG, jSONObject.toString());
ArrayList<Friend> tempFriends = new ArrayList<Friend>();
try {
if(jSONObject.getInt("success") == 1){
JSONArray jsonArray = jSONObject.getJSONArray("users");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject o = jsonArray.getJSONObject(i);
tempFriends.add(new Friend(o.getString("user_name"), new LatLng(o.getDouble("loc_y"), o.getDouble("loc_x")), false));
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return tempFriends;
}
}
public ArrayList<Friend> loadLocation(String URL, String userName) throws InterruptedException, ExecutionException {
return new LoadLocations().execute(URL, userName).get();
}
MapActivity:
public class MapActivity extends Activity implements LocationSource, LocationListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private Thread loadFriendLocations = new Thread()
{
@Override
public void run() {
Log.d(TAG, "LastKnownLocation: " + locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));
try {
while(true) {
controller.loadLocations(LOAD_LOCATIONS);
Log.d(TAG, "Loading new locations");
Message msg = uIHandler.obtainMessage();
msg.what = ADD_MAP_PIN;
uIHandler.sendMessage(msg);
sleep(10000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
final Handler uIHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==ADD_MAP_PIN){
for (Friend friend : controller.getFriends()) {
addMapPin(friend);
}
}
super.handleMessage(msg);
}
};
Странно, что я могу запустить это приложение на своем эмуляторе (API 16), и он работает просто отлично, но когда я пытаюсь запустить его на физическом устройстве (API 15), он получает эту ошибку. AsyncTask запускается в отдельном классе, поэтому может возникнуть проблема. Буду признателен за любые предложения. Заранее спасибо.
Вы не можете выполнить AsyncTask
из фонового потока. См. Раздел "Правила Threading" документация AsyncTask
.
У меня была аналогичная проблема, проблема заключалась в том, что у меня была серия Thread из Main Thread. Фактически Main UI Thread начал службу, которая выполнялась на службе, а затем запустила другой поток, в котором, наконец, был FileObserver (другой поток), мне пришлось общаться с потоком пользовательского интерфейса, вставив тост-сообщение. Я пробовал несколько часов и пробовал ниже, он работал как прелесть.
//Let this be the code in your n'th level thread from main UI thread
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Toast.makeText(context, "Your message to main thread", Toast.LENGTH_SHORT).show();
}
});
Основным ключом здесь является функция getMainLooper() класса Looper, которая предоставит вам Looper против основного потока пользовательского интерфейса.
Сделайте это в фоновом режиме...
runOnUiThread(new Runnable() {
public void run()
{
if (items.equals("null"))
{
Toast.makeText(getApplicationContext(), "No Event Found",Toast.LENGTH_LONG).show();
}
else {
}
}
});