因此,有一个背景服务,一旦GPS 位置发生变化,就会创建可运行对象。 Runnable
包含HTTPConnection
以进行POST,并通过sendBroadcast()
两次发送广播消息。
因此,如果没有机会通过此方案发送数据,我遇到的问题就会发生,应用程序就会崩溃。
重新构建代码的任何线索,或者当新的TaskAsync
准备就绪时,可能会更改TaskAsync
和取消待处理 TaskAsync
的方法吗?
有任何线索吗?
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.text.format.DateFormat;
import android.util.Log;
import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
public class gps_service2 extends Service {
private static final String TAG = "GPS SERVICE";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 10000;
private static final float LOCATION_DISTANCE = 10f;
Context context;
private class LocationListener implements android.location.LocationListener
{
Location mLastLocation;
public LocationListener(String provider)
{
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
@Override
public void onLocationChanged(Location location)
{
Log.e(TAG, "onLocationChanged: " + location);
try
{
ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(context, "App_Settings", 0);
AppSettings appSettings = complexPreferences.getObject("App_Settings", AppSettings.class);
if (appSettings != null) {
LocationItem locationItem = new LocationItem();
locationItem.DeviceID = appSettings.getDeviceID();
locationItem.Latitude = Double.toString(location.getLatitude());
locationItem.Longitude = Double.toString(location.getLongitude());
Date d = new Date();
CharSequence timeOfRequest = DateFormat.format("yyyy-MM-dd HH:mm:ss", d.getTime()); // YYYY-MM-DD HH:mm:ss
locationItem.TimeOfRequest = timeOfRequest.toString();
locationItem.SerialNumber = appSettings.getSerialNumber();
Gson gson = new Gson();
String requestObject = gson.toJson(locationItem);
String url = appSettings.getIpAddress() + "/api/staff/savedata";
makeRequest(url, requestObject, dLocation);
}
}
catch (Exception ex)
{
}
}
@Override
public void onProviderDisabled(String provider)
{
Log.e(TAG, "onProviderDisabled: " + provider);
}
@Override
public void onProviderEnabled(String provider)
{
Log.e(TAG, "onProviderEnabled: " + provider);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.e(TAG, "onStatusChanged: " + provider);
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
@Override
public IBinder onBind(Intent arg0)
{
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onCreate()
{
context = this;
Log.e(TAG, "onCreate");
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
@Override
public void onDestroy()
{
Log.e(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
public void makeRequest(String uri, String json, DLocation dLocation) {
HandlerThread handlerThread = new HandlerThread("URLConnection");
handlerThread.start();
Handler mainHandler = new Handler(handlerThread.getLooper());
Runnable myRunnable = createRunnable(uri, json, dLocation);
mainHandler.post(myRunnable);
}
private Runnable createRunnable(final String uri, final String data,final DLocation dLocation){
Runnable aRunnable = new Runnable(){
public void run(){
try {
//Connect
HttpURLConnection urlConnection;
urlConnection = (HttpURLConnection) ((new URL(uri).openConnection()));
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestMethod("POST");
urlConnection.connect();
//Write
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
try {
writer.write(data);
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,"Ошибка записи в буфер для пережачи по HTTP");
}
writer.close();
outputStream.close();
//Read
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
String result = sb.toString();
Log.d(TAG, result);
Intent iResult = new Intent("location_update");
DLocation dLocation = new DLocation();
iResult.putExtra("result", dLocation);
sendBroadcast(iResult);
}catch( Exception err){
err.printStackTrace();
Log.d(TAG, "HTTP " + err.getMessage());
}
}
};
return aRunnable;
}
}
答案 0 :(得分:5)
Runnable只是一个接口,当你使用Runnable接口创建一个线程时,它基本上会在它创建的线程下运行,在这里运行与UI线程的关联,根据谷歌文档网络调用必须在工作线程中在UI线程中。
那么为什么它在模拟器上运行
android有DVM(dalvik虚拟机),它的工作方式与JVM类似,但不是.class文件,DVM使用.dex扩展名,因此设备可能有较旧或较新版本的DVM。
<强>修正强>
使用android的AsyncTask进行网络调用。 android(DVM)与JVM相比资源有限,说到线程,所以最好使用AsyncTask
用于将JSON传递给服务器的AsyncTask代码,并以回调方式响应
public class WebService extends AsyncTask<String,String,String> {
private static final String TAG="SyncToServerTAG";
private String urlString;
private JSONObject jsonObject=null;
private int screenId=1;
public WebService(String url) {
this.urlString=url;
}
public WebService(Context context, String url, JSONObject jsonObject) {
this.urlString = url;
this.jsonObject = jsonObject;
}
@Override
protected String doInBackground(String... strings) {
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setChunkedStreamingMode(0);
urlConnection.setConnectTimeout(5000);
urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setRequestMethod("POST");
if(jsonObject!=null) {
OutputStream os = urlConnection.getOutputStream();
os.write(jsonObject.toString().getBytes("UTF-8"));
}
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(
(urlConnection.getInputStream())));
String output="";
while (true) {
String line=br.readLine();
Log.d(TAG,line+" ");
if(line!=null)
output+=line;
else
break;
}
in.close();
urlConnection.disconnect();
JSONObject j;
if(output.equals(""))
publishProgress("Server give null");
else {
j=new JSONObject(output);
return output;
}
return output;
} catch (MalformedURLException e) {
e.printStackTrace();
publishProgress(e.toString());
} catch (IOException e) {
e.printStackTrace();
publishProgress(e.toString());
} catch (JSONException e) {
e.printStackTrace();
publishProgress(e.toString());
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
fireError(values[0]);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(s!=null) {
try {
JSONObject jsonObject=new JSONObject(s);
fireComplete(0, jsonObject);
} catch (JSONException e) {
e.printStackTrace();
fireError("Non acceptable responds from server ["+urlString+"]");
}
}
}
public interface OnWebCompleteListener{
void onComplete(JSONObject result, int dataSource);
void onError(String error);
}
private OnWebCompleteListener onWebCompleteListener;
private void fireComplete(int sourse,JSONObject cache){
if(onWebCompleteListener!=null)
onWebCompleteListener.onComplete(cache,sourse);
}
private void fireError(String message){
if(onWebCompleteListener!=null)
onWebCompleteListener.onError(message);
}
public void start(OnWebCompleteListener onWebCompleteListener){
if(onWebCompleteListener==null)
throw new RuntimeException("You must provide non-null value as start listener");
this.onWebCompleteListener=onWebCompleteListener;
execute((String)null);
}
}
<强>用法强>
WebService webService=new WebService(context,"url",jsonObject);
webService.start(new WebService.OnWebCompleteListener() {
@Override
public void onComplete(JSONObject result, int dataSource) {
}
@Override
public void onError(String error) {
}
});
答案 1 :(得分:1)
您的代码非常容易受到攻击。我认为你崩溃是因为你的makeRequest方法退出之前你Runnable有机会完成任务。 您在发送资源后立即关闭资源,从而释放系统资源。 你第二次打电话给广播,资源不再存在导致崩溃....