Android 使用服务解析json数据
我试图通过服务从json格式的网页获取数据库中的行数。为什么我的代码不允许我这样做 我的服务:Android 使用服务解析json数据,android,json,service,Android,Json,Service,我试图通过服务从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; p
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表示无法实例化服务
///编辑//
完整日志:
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
从你的全部日志中 原因:android.os.NetworkOnMainThreadException 基本上,您不能在长时间运行的主(UI)线程上执行任何操作,所有网络操作都被视为潜在的长时间运行,并将引发该异常 即使安卓
服务
是“不可见的”,即它没有UI,它仍然在主线程上运行
两种可能的修复方法是在服务中创建一个单独的线程来下载,或者简单地使用IntentService
IntentService
类扩展了Service
,但它使用自己的工作线程来完成它需要做的事情,然后自行终止
有关详细信息,请参阅文档
也看到
编辑:移动这两行
UpdaterJson jsonUpdater = new UpdaterJson();
JSONObject json = jsonUpdater.getJSONFromUrl(UPDATE_URL);
…在onHandleContent(…)
方法的内部
这不是台词
count = json.getInt(TAG_ROWCOUNT);
…这导致了NetworkOnMainThreadException
-这是您实际从URL获取JSON的时候。在创建服务(NotificationService)时,将下面两行移动
json.getInt(“rowcount”)
注意,在{“rowcount”:2}
中,2
没有引号,这使得它成为一个整数
/长
…等等。您需要从logcat和您启动此服务的位置发布更多信息,以便我们可以帮助您这是我尝试的第一件事,似乎不起作用。请在这里发布日志,以及在哪里/如何启动此服务“logcat说无法实例化服务。”我猜?你得到了一个NetworkOnMainThreadException
,但是除非你真的发布了logcat输出,否则没有人能确定。谢谢你的回复,我已经发布了完整的logcat数据。IntentService对我来说是相当新的。我是否将与获取json相关的代码放在onhandleIntent或onstartcommand中?你是在要求一个意图吗?我没有意图的用处。关于如何使用IntentService类,你能说得更具体些吗?@crushman:我在我的答案中添加了另一个链接。IntentService
类与Service
有点不同,因为它处理自己的工作线程,也会自动终止,但通常使用起来非常简单。Intent
不需要任何特定的内容-只需添加一个“操作”,例如com.mycompany.myapp.DOWNLOAD\u JSON
。IntentService
代码可以忽略它,如果您只想让它做一件事。是的,onHandleIntent(…)
方法起作用。似乎你是对的,Squonk,IntentService实际上比服务本身容易得多,但它并没有解决我遇到的问题。我仍然在logcat中遇到同样的错误。我已经在我的问题中添加了我的新服务,这样你就可以看到我是如何改变它的。请看一看,你是最聪明的!!它成功了,我没想到会这么简单。谢谢你的帮助。
count = json.getInt(TAG_ROWCOUNT);
UpdaterJson jsonUpdater = new UpdaterJson();
JSONObject json = jsonUpdater.getJSONFromUrl(UPDATE_URL);