我正在从Fragment调用一个名为MapsActivity的Activity。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_one, container, false);
ibTrackEmp = (ImageView)rootView.findViewById(R.id.ibTrackEmp);
ibTrackEmp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), MapsActivity.class);
startActivity(intent);
}
});
return rootView;
}
现在,在MapsActivity.java中,我将Web服务称为BackGround任务
private class GetALLGPSTask extends AsyncTask<String, Void, String> {
private TextView textView;
public GetALLGPSTask() {
}
@Override
protected String doInBackground(String... strings) {
String result = "Unable to fetch from SAP";
try {
URL url = new URL(strings[0]);
final String basicAuth = "Basic " + Base64.encodeToString("xxxx:xxxx@1223".getBytes(), Base64.NO_WRAP);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(90000);
urlConnection.setConnectTimeout(55000);
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty ("Authorization", basicAuth);
InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
String inputString;
while ((inputString = bufferedReader.readLine()) != null) {
builder.append(inputString);
}
int responsecode = urlConnection.getResponseCode();
Log.d("ResponseCode", String.valueOf(responsecode));
if(responsecode == 200){
result = "GPS Coordinates Updated Successfully";
try {
JSONArray jsonArray = new JSONArray(builder.toString());
List<Pair<String, String>> allNames = new ArrayList<>();
final int numberOfItemsInResp = jsonArray.length();
for (int i = 0; i < numberOfItemsInResp; i++) {
JSONObject jobj = jsonArray.getJSONObject(i);
String name = jobj.getString("NAME");
String addlatitude = jobj.getString("LATITUDE");
String addlongitude = jobj.getString("LONGITUDE");
LatLng newemp = new LatLng(Double.valueOf(addlatitude), Double.valueOf(addlongitude));
mMap.addMarker(new MarkerOptions().position(newemp).title("UserName: "+name));
}
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
}
urlConnection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
@Override
protected void onPostExecute(String temp) {
Toast.makeText(MapsActivity.this,
temp, Toast.LENGTH_SHORT).show();
}
此处,Web服务正在调用,但应用程序初始化为第一个屏幕。 我收到以下错误日志
--------- beginning of crash
09-27 15:52:31.912 31508-31767/com.example.sd0003.appslider E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.example.sd0003.appslider, PID: 31508
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalStateException: Not on the main thread
at maps.w.d.a(Unknown Source)
at maps.y.F.a(Unknown Source)
at maps.ad.t.a(Unknown Source)
at ua.onTransact(:com.google.android.gms.DynamiteModulesB:167)
at android.os.Binder.transact(Binder.java:392)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$zza$zza.addMarker(Unknown Source)
at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source)
at com.example.sd0003.appslider.MapsActivity$GetALLGPSTask.doInBackground(MapsActivity.java:152)
at com.example.sd0003.appslider.MapsActivity$GetALLGPSTask.doInBackground(MapsActivity.java:105)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
09-27 15:52:31.912 31508-31767/com.example.sd0003.appslider E/AbstractTracker: Can't create handler inside thread that has not called Looper.prepare()
09-27 15:52:31.913 31508-31767/com.example.sd0003.appslider D/AppTracker: App Event: crash
09-27 15:52:31.916 31508-31767/com.example.sd0003.appslider E/AbstractTracker: mTrackerAsyncQueryHandler is null
09-27 15:52:31.942 31508-31767/com.example.sd0003.appslider I/Process: Sending signal. PID: 31508 SIG: 9
答案 0 :(得分:1)
您不应该从后台线程执行UI更新。在这种特殊情况下,您不应该在mMap
引用中添加标记。
相反,您应该返回位置名称和纬度/经度对的列表,并处理从onPostExecute
中的主线程更新UI。考虑返回类似于List<Pair<String, LatLng>> locations
的数据集。
您的实施将如下所示:
private class GetALLGPSTask extends AsyncTask<String, Void, List<Pair<String, LatLng>>> {
private TextView textView;
public GetALLGPSTask() {
}
@Override
protected List<Pair<String, LatLng>> doInBackground(String... strings) {
List<Pair<String, LatLng>> allLocations = new ArrayList<>();
try {
URL url = new URL(strings[0]);
final String basicAuth = "Basic " + Base64.encodeToString("xxxx:xxxx@1223".getBytes(), Base64.NO_WRAP);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(90000);
urlConnection.setConnectTimeout(55000);
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty ("Authorization", basicAuth);
InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
String inputString;
while ((inputString = bufferedReader.readLine()) != null) {
builder.append(inputString);
}
int responsecode = urlConnection.getResponseCode();
Log.d("ResponseCode", String.valueOf(responsecode));
if(responsecode == 200){
try {
JSONArray jsonArray = new JSONArray(builder.toString());
final int numberOfItemsInResp = jsonArray.length();
for (int i = 0; i < numberOfItemsInResp; i++) {
JSONObject jobj = jsonArray.getJSONObject(i);
String name = jobj.getString("NAME");
String latitude = jobj.getString("LATITUDE");
String longitude = jobj.getString("LONGITUDE");
LatLng latLng = new LatLng(Double.valueOf(addlatitude), Double.valueOf(addlongitude));
allLocations.add(new Pair<>(name, latLng))
}
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
}
urlConnection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return allLocations;
}
@Override
protected void onPostExecute(List<Pair<String, LatLng>> locations) {
for (Pair<String, LatLng> location : locations) {
mMap.addMarker(new MarkerOptions().position(location.second).title("UserName: " + location.first));
}
}
}
旁注:您的allNames
列表从未使用过。