我试图通过服务从json格式的网页获取数据库中的行数。为什么我的代码不允许我这样做?
我的服务:
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class NotificationService extends Service {
private static final String TAG = NotificationService.class.getSimpleName();
private static final String UPDATE_URL = "http://192.168.1.6/webservice/updatecheck.php";
private static final String TAG_ROWCOUNT = "rowcount";
int count;
UpdaterJson jsonUpdater = new UpdaterJson();
JSONObject json = jsonUpdater.getJSONFromUrl(UPDATE_URL);
@Override
//bind an activity to a service
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d(TAG, "onCreate");
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.d(TAG, "onstartcommand");
try {
count = json.getInt(TAG_ROWCOUNT);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "count "+count, Toast.LENGTH_LONG).show();
return START_STICKY;
}
我的JsonParser:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class UpdaterJson {
final String TAG = "JsonParser.java";
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
public JSONObject getJSONFromUrl(String url) {
// make HTTP request
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e(TAG, "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e(TAG, "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
网页输出:
{"rowcount":2}
Logcat说无法实例化服务。
///编辑// 完整的logcat:
03-23 20:02:07.240: E/AndroidRuntime(7989): FATAL EXCEPTION: main
03-23 20:02:07.240: E/AndroidRuntime(7989): java.lang.RuntimeException: Unable to instantiate service com.wordpress.yourhappening.happening.NotificationService: android.os.NetworkOnMainThreadException
03-23 20:02:07.240: E/AndroidRuntime(7989): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2561)
03-23 20:02:07.240: E/AndroidRuntime(7989): at android.app.ActivityThread.access$1600(ActivityThread.java:141)
03-23 20:02:07.240: E/AndroidRuntime(7989): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1338)
03-23 20:02:07.240: E/AndroidRuntime(7989): at android.os.Handler.dispatchMessage(Handler.java:99)
03-23 20:02:07.240: E/AndroidRuntime(7989): at android.os.Looper.loop(Looper.java:137)
03-23 20:02:07.240: E/AndroidRuntime(7989): at android.app.ActivityThread.main(ActivityThread.java:5103)
03-23 20:02:07.240: E/AndroidRuntime(7989): at java.lang.reflect.Method.invokeNative(Native Method)
03-23 20:02:07.240: E/AndroidRuntime(7989): at java.lang.reflect.Method.invoke(Method.java:525)
03-23 20:02:07.240: E/AndroidRuntime(7989): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
03-23 20:02:07.240: E/AndroidRuntime(7989): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-23 20:02:07.240: E/AndroidRuntime(7989): at dalvik.system.NativeStart.main(Native Method)
03-23 20:02:07.240: E/AndroidRuntime(7989): Caused by: android.os.NetworkOnMainThreadException
03-23 20:02:07.240: E/AndroidRuntime(7989): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)
03-23 20:02:07.240: E/AndroidRuntime(7989): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
03-23 20:02:07.240: E/AndroidRuntime(7989): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
03-23 20:02:07.240: E/AndroidRuntime(7989): at libcore.io.IoBridge.connect(IoBridge.java:112)
03-23 20:02:07.240: E/AndroidRuntime(7989): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
03-23 20:02:07.240: E/AndroidRuntime(7989): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
03-23 20:02:07.240: E/AndroidRuntime(7989): at java.net.Socket.connect(Socket.java:842)
03-23 20:02:07.240: E/AndroidRuntime(7989): at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
03-23 20:02:07.240: E/AndroidRuntime(7989): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
03-23 20:02:07.240: E/AndroidRuntime(7989): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
03-23 20:02:07.240: E/AndroidRuntime(7989): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
03-23 20:02:07.240: E/AndroidRuntime(7989): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
03-23 20:02:07.240: E/AndroidRuntime(7989): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
03-23 20:02:07.240: E/AndroidRuntime(7989): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
03-23 20:02:07.240: E/AndroidRuntime(7989): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
03-23 20:02:07.240: E/AndroidRuntime(7989): at com.wordpress.yourhappening.happening.UpdaterJson.getJSONFromUrl(UpdaterJson.java:35)
03-23 20:02:07.240: E/AndroidRuntime(7989): at com.wordpress.yourhappening.happening.NotificationService.<init>(NotificationService.java:19)
03-23 20:02:07.240: E/AndroidRuntime(7989): at java.lang.Class.newInstanceImpl(Native Method)
03-23 20:02:07.240: E/AndroidRuntime(7989): at java.lang.Class.newInstance(Class.java:1130)
03-23 20:02:07.240: E/AndroidRuntime(7989): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2558)
03-23 20:02:07.240: E/AndroidRuntime(7989): ... 10 more
////切换到IntentService后编辑
import org.json.JSONException;
import org.json.JSONObject;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
public class NotificationService extends IntentService {
public NotificationService() {
super("NotificationService");
// TODO Auto-generated constructor stub
}
private static final String TAG = NotificationService.class.getSimpleName();
private static final String UPDATE_URL = "http://192.168.1.6/webservice/updatecheck.php";
public static final String TAG_ROWCOUNT = "rowcount";
int count;
UpdaterJson jsonUpdater = new UpdaterJson();
JSONObject json = jsonUpdater.getJSONFromUrl(UPDATE_URL);
@Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Log.d(TAG, "onHandle");
try {
count = json.getInt(TAG_ROWCOUNT);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
答案 0 :(得分:1)
从您的完整logcat ...
引起:android.os.NetworkOnMainThreadException
基本上你不能在长时间运行的主(UI)线程上做任何事情,并且所有网络操作都被认为可能长时间运行并且会抛出该异常。
即使Android Service
是不可见的,也就是说,它没有UI,但它仍然在主线程上运行。
两种可能的修复方法是在Thread
中创建单独的Service
进行下载,或者只使用IntentService
。
IntentService
类扩展Service
但它使用自己的工作线程来执行它需要做的事情,然后自行终止。
编辑:移动这两行...
UpdaterJson jsonUpdater = new UpdaterJson();
JSONObject json = jsonUpdater.getJSONFromUrl(UPDATE_URL);
...在onHandleIntent(...)
方法内部。
不是这条线......
count = json.getInt(TAG_ROWCOUNT);
...当您真正从网址获取JSON时,会导致NetworkOnMainThreadException
-
答案 1 :(得分:0)
在服务的onCreate(NotificationService)中移动以下两行
UpdaterJson jsonUpdater = new UpdaterJson();
JSONObject json = jsonUpdater.getJSONFromUrl(UPDATE_URL);