Android谷歌地图崩溃
问题描述:
我有我的谷歌地图在我的应用程序之前工作。现在我已经添加了从我的PHP服务器获取的代码,现在它正在崩溃,我不知道为什么。我确信JSON是正确的。它应该做的是联系我的服务器,获取位置列表并使用标记在地图上输入它们。我也尝试在异步中做到这一点,但在搜索后发现我无法从后台更改UI。Android谷歌地图崩溃
MY MAP.JAVA
public class Map extends FragmentActivity implements OnInfoWindowClickListener
{
private GoogleMap map;
private int zoomLevel = 10;
static JSONObject object =null;
// flag for Internet connection status
Boolean isInternetPresent = false;
// Connection detector class
Connection cd;
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.mapnav, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_add:
// Single menu item is selected do something
// Ex: launching new activity/screen or show alert message
Toast.makeText(this, "Add place is Selected", Toast.LENGTH_SHORT).show();
Intent A = new Intent(this, Add.class);
startActivity(A);
return true;
case R.id.action_events:
// Single menu item is selected do something
// Ex: launching new activity/screen or show alert message
Toast.makeText(this, "Events is Selected", Toast.LENGTH_SHORT).show();
Intent E = new Intent(this, Events.class);
startActivity(E);
return true;
case R.id.action_map:
Toast.makeText(this, "Map is Selected", Toast.LENGTH_SHORT).show();
Intent M = new Intent(this, Map.class);
startActivity(M);
return true;
case R.id.action_chat:
Toast.makeText(this, "Chat is Selected", Toast.LENGTH_SHORT).show();
Intent c = new Intent(this, Chat.class);
startActivity(c);
return true;
case R.id.action_settings:
Toast.makeText(this, "Settings is Selected", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.map_layout);
JsonParser jsonParser = new JsonParser();
String json = jsonParser.getJSONFromUrl("http://www.mywebsite.com/test.json");
if (json != null)
{
try
{
JSONObject parent = new JSONObject(json);
JSONArray eventDetails = parent.getJSONArray("maps");
for(int i=0; i < eventDetails.length(); i++)
{
object = eventDetails.getJSONObject(i);
String getName = object.getString("name");
String getAddy =object.getString("addy");
String getHours = object.getString("hours");
String getDesc = object.getString("desc");
String getLat = object.getString("lat");
String getLong = object.getString("long");
Log.e("JSON", "> " + getName + getAddy + getHours + getDesc + getLat + getLong);
// creating connection detector class instance
cd = new Connection(getApplicationContext());
try
{
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
// Get name of best provider
String provider = locationManager.getBestProvider(criteria, true);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
if (map!=null)
{
map.getUiSettings().setCompassEnabled(true);
map.setTrafficEnabled(true);
map.setMyLocationEnabled(true);
// My current location
Location myloc = locationManager.getLastKnownLocation(provider);
// Get latitude of current location
double latitude = myloc.getLatitude();
// Get longitude of current location
double longitude = myloc.getLongitude();
double lat = Double.valueOf(getLat);
double lng = Double.valueOf(getLong);
// create latlng
LatLng mylocation = new LatLng(latitude, longitude);
// Move the camera instantly to defaultLatLng.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(mylocation, zoomLevel));
LatLng location = new LatLng(lat, lng);
map.addMarker(new MarkerOptions().position(location)
.title(getName)
.snippet(getHours)
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.icon)));
// map.setOnInfoWindowClickListener(this);
}
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
}
catch (JSONException e)
{
// TODO Auto-generated catch block
Log.e("Json Error", "Error: " + e.toString());
e.printStackTrace();
}
}
}
@SuppressWarnings("deprecation")
public void showAlertDialog(Context context, String title, String message, Boolean status) {
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
// Setting Dialog Title
alertDialog.setTitle(title);
// Setting Dialog Message
alertDialog.setMessage(message);
// Setting alert dialog icon
alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail);
// Setting OK Button
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
Intent intent = new Intent(getApplicationContext(), Navigation.class);
startActivity(intent);
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onPause()
{
if (map != null)
{
map.setMyLocationEnabled(false);
map.setTrafficEnabled(false);
}
super.onPause();
}
@Override
public void onInfoWindowClick(Marker marker)
{
Intent intent = new Intent(this, Map_layout.class);
intent.putExtra("snippet", marker.getSnippet());
intent.putExtra("title", marker.getTitle());
intent.putExtra("position", marker.getPosition());
startActivity(intent);
}
private class PrefetchData extends AsyncTask<Void, Void, Void>
{
@Override
protected void onPreExecute()
{
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... arg0)
{
return null;
}
}
}
MY logcat的
01-25 18:46:36.142: E/AndroidRuntime(7482): FATAL EXCEPTION: main
01-25 18:46:36.142: E/AndroidRuntime(7482): Process: com.databasedemo, PID: 7482
01-25 18:46:36.142: E/AndroidRuntime(7482): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.databasedemo/com.databasedemo.Map}: android.os.NetworkOnMainThreadException
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.app.ActivityThread.access$800(ActivityThread.java:135)
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.os.Handler.dispatchMessage(Handler.java:102)
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.os.Looper.loop(Looper.java:136)
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.app.ActivityThread.main(ActivityThread.java:5017)
01-25 18:46:36.142: E/AndroidRuntime(7482): at java.lang.reflect.Method.invokeNative(Native Method)
01-25 18:46:36.142: E/AndroidRuntime(7482): at java.lang.reflect.Method.invoke(Method.java:515)
01-25 18:46:36.142: E/AndroidRuntime(7482): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
01-25 18:46:36.142: E/AndroidRuntime(7482): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
01-25 18:46:36.142: E/AndroidRuntime(7482): at dalvik.system.NativeStart.main(Native Method)
01-25 18:46:36.142: E/AndroidRuntime(7482): Caused by: android.os.NetworkOnMainThreadException
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
01-25 18:46:36.142: E/AndroidRuntime(7482): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
01-25 18:46:36.142: E/AndroidRuntime(7482): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
01-25 18:46:36.142: E/AndroidRuntime(7482): at java.net.InetAddress.getAllByName(InetAddress.java:214)
01-25 18:46:36.142: E/AndroidRuntime(7482): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnec tionOperator.java:137)
01-25 18:46:36.142: E/AndroidRuntime(7482): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
01-25 18:46:36.142: E/AndroidRuntime(7482): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
01-25 18:46:36.142: E/AndroidRuntime(7482): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
01-25 18:46:36.142: E/AndroidRuntime(7482): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
01-25 18:46:36.142: E/AndroidRuntime(7482): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
01-25 18:46:36.142: E/AndroidRuntime(7482): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
01-25 18:46:36.142: E/AndroidRuntime(7482): at com.databasedemo.JsonParser.getJSONFromUrl(JsonParser.java:35)
01-25 18:46:36.142: E/AndroidRuntime(7482): at com.databasedemo.Map.onCreate(Map.java:97)
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.app.Activity.performCreate(Activity.java:5231)
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-25 18:46:36.142: E/AndroidRuntime(7482): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
01-25 18:46:36.142: E/AndroidRuntime(7482): ... 11 more
// EDIT运行在后台...
public class Map extends FragmentActivity implements OnInfoWindowClickListener
{
private GoogleMap map;
private int zoomLevel = 10;
static JSONObject object =null;
// flag for Internet connection status
Boolean isInternetPresent = false;
// Connection detector class
Connection cd;
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.mapnav, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_add:
// Single menu item is selected do something
// Ex: launching new activity/screen or show alert message
Toast.makeText(this, "Add place is Selected", Toast.LENGTH_SHORT).show();
Intent A = new Intent(this, Add.class);
startActivity(A);
return true;
case R.id.action_events:
// Single menu item is selected do something
// Ex: launching new activity/screen or show alert message
Toast.makeText(this, "Events is Selected", Toast.LENGTH_SHORT).show();
Intent E = new Intent(this, Events.class);
startActivity(E);
return true;
case R.id.action_map:
Toast.makeText(this, "Map is Selected", Toast.LENGTH_SHORT).show();
Intent M = new Intent(this, Map.class);
startActivity(M);
return true;
case R.id.action_chat:
Toast.makeText(this, "Chat is Selected", Toast.LENGTH_SHORT).show();
Intent c = new Intent(this, Chat.class);
startActivity(c);
return true;
case R.id.action_settings:
Toast.makeText(this, "Settings is Selected", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.map_layout);
new PrefetchData().execute();
}
@SuppressWarnings("deprecation")
public void showAlertDialog(Context context, String title, String message, Boolean status) {
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
// Setting Dialog Title
alertDialog.setTitle(title);
// Setting Dialog Message
alertDialog.setMessage(message);
// Setting alert dialog icon
alertDialog.setIcon((status) ? R.drawable.success : R.drawable.fail);
// Setting OK Button
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
Intent intent = new Intent(getApplicationContext(), Navigation.class);
startActivity(intent);
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onPause()
{
if (map != null)
{
map.setMyLocationEnabled(false);
map.setTrafficEnabled(false);
}
super.onPause();
}
@Override
public void onInfoWindowClick(Marker marker)
{
Intent intent = new Intent(this, Map_layout.class);
intent.putExtra("snippet", marker.getSnippet());
intent.putExtra("title", marker.getTitle());
intent.putExtra("position", marker.getPosition());
startActivity(intent);
}
private class PrefetchData extends AsyncTask<Void, Void, Void>
{
@Override
protected void onPreExecute()
{
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... arg0)
{
JsonParser jsonParser = new JsonParser();
String json = jsonParser.getJSONFromUrl("http://www.mywebsite.com/test.json");
if (json != null)
{
try
{
JSONObject parent = new JSONObject(json);
JSONArray eventDetails = parent.getJSONArray("maps");
for(int i=0; i < eventDetails.length(); i++)
{
object = eventDetails.getJSONObject(i);
String getName = object.getString("name");
String getAddy =object.getString("addy");
String getHours = object.getString("hours");
String getDesc = object.getString("desc");
String getLat = object.getString("lat");
String getLong = object.getString("long");
Log.e("JSON", "> " + getName + getAddy + getHours + getDesc + getLat + getLong);
// creating connection detector class instance
cd = new Connection(getApplicationContext());
try
{
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
// Get name of best provider
String provider = locationManager.getBestProvider(criteria, true);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
if (map!=null)
{
map.getUiSettings().setCompassEnabled(true);
map.setTrafficEnabled(true);
map.setMyLocationEnabled(true);
// My current location
Location myloc = locationManager.getLastKnownLocation(provider);
// Get latitude of current location
double latitude = myloc.getLatitude();
// Get longitude of current location
double longitude = myloc.getLongitude();
double lat = Double.valueOf(getLat);
double lng = Double.valueOf(getLong);
// create latlng
LatLng mylocation = new LatLng(latitude, longitude);
// Move the camera instantly to defaultLatLng.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(mylocation, zoomLevel));
LatLng location = new LatLng(lat, lng);
map.addMarker(new MarkerOptions().position(location)
.title(getName)
.snippet(getHours)
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.icon)));
// map.setOnInfoWindowClickListener(this);
}
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
}
catch (JSONException e)
{
// TODO Auto-generated catch block
Log.e("Json Error", "Error: " + e.toString());
e.printStackTrace();
}
}
return null;
}
}
}
// LOG CAT运行在后台
01-25 18:58:20.042: E/AndroidRuntime(7593): FATAL EXCEPTION: AsyncTask #1
01-25 18:58:20.042: E/AndroidRuntime(7593): Process: com.databasedemo, PID: 7593
01-25 18:58:20.042: E/AndroidRuntime(7593): java.lang.RuntimeException: An error occured while executing doInBackground()
01-25 18:58:20.042: E/AndroidRuntime(7593): at android.os.AsyncTask$3.done(AsyncTask.java:300)
01-25 18:58:20.042: E/AndroidRuntime(7593): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
01-25 18:58:20.042: E/AndroidRuntime(7593): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
01-25 18:58:20.042: E/AndroidRuntime(7593): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
01-25 18:58:20.042: E/AndroidRuntime(7593): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
01-25 18:58:20.042: E/AndroidRuntime(7593): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
01-25 18:58:20.042: E/AndroidRuntime(7593): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
01-25 18:58:20.042: E/AndroidRuntime(7593): at java.lang.Thread.run(Thread.java:841)
01-25 18:58:20.042: E/AndroidRuntime(7593): Caused by: java.lang.IllegalStateException: Not on the main thread
01-25 18:58:20.042: E/AndroidRuntime(7593): at maps.aq.o.b(Unknown Source)
01-25 18:58:20.042: E/AndroidRuntime(7593): at maps.ak.g.b(Unknown Source)
01-25 18:58:20.042: E/AndroidRuntime(7593): at maps.af.al.k(Unknown Source)
01-25 18:58:20.042: E/AndroidRuntime(7593): at clz.onTransact(SourceFile:304)
01-25 18:58:20.042: E/AndroidRuntime(7593): at android.os.Binder.transact(Binder.java:361)
01-25 18:58:20.042: E/AndroidRuntime(7593): at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.getUiSettings(Unknown Source)
01-25 18:58:20.042: E/AndroidRuntime(7593): at com.google.android.gms.maps.GoogleMap.getUiSettings(Unknown Source)
01-25 18:58:20.042: E/AndroidRuntime(7593): at com.databasedemo.Map$PrefetchData.doInBackground(Map.java:198)
01-25 18:58:20.042: E/AndroidRuntime(7593): at com.databasedemo.Map$PrefetchData.doInBackground(Map.java:1)
01-25 18:58:20.042: E/AndroidRuntime(7593): at android.os.AsyncTask$2.call(AsyncTask.java:288)
01-25 18:58:20.042: E/AndroidRuntime(7593): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
01-25 18:58:20.042: E/AndroidRuntime(7593): ... 4 more
答
如上所述,正确的方法是使用AsyncTask。 AsyncTask有3个关键组件,你需要两个。第三个是进展,这看起来并不像你需要的那样,因为你只做一个网络电话。您将使用这两个是:
-
doInBackground
- 这是东西,需要很长的时间,如网络运营,应该发生。通常你会从这里找到一些东西传递给主线程,比如位图或字符串,或者甚至完全是其他东西。 -
onPostExecute
- 这是用户界面的东西去的地方。 Android只允许一个线程访问UI,所有其他线程必须将内容传递给UI线程才能工作,或者在UI上进行操作。事实证明onPostExecute总是在UI线程上运行。
你需要做的就是弄清楚哪一块是网络连接,哪一块是UI操作,以及需要在它们之间流动以使其工作。 Android API docs展示了如何完成这项工作的一个例子。
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i/(float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
答
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.databasedemo/com.databasedemo.Map}: android.os.NetworkOnMainThreadException
您正在UI Thread
上运行网络操作。由于API 11,您不能再在UI Thread
上执行长时间运行的任务。你确实有一个AsyncTask
,但你没有使用它。
在您更新的问题中,您使用的是AsyncTask
,但您试图从背景Thread
操纵UI元素。您应该使用AsyncTask
的onPostExecute()
来更新UI。
但是,当我把它放在AsyncTask的背景上时,我也会得到错误。让我在后台运行它并发布该日志猫。 – Jayce
这是因为你需要学习如何正确实现'AsyncTask'。 – Emmanuel
看看我更新的答案。 – Emmanuel