使用服务解析json数据

时间:2014-03-24 00:04:28

标签: 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;

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();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

从您的完整logcat ...

  

引起:android.os.NetworkOnMainThreadException

基本上你不能在长时间运行的主(UI)线程上做任何事情,并且所有网络操作都被认为可能长时间运行并且会抛出该异常。

即使Android Service是不可见的,也就是说,它没有UI,但它仍然在主线程上运行。

两种可能的修复方法是在Thread中创建单独的Service进行下载,或者只使用IntentService

IntentService类扩展Service但它使用自己的工作线程来执行它需要做的事情,然后自行终止。

请参阅IntentService

的文档

另见Extending IntentService

编辑:移动这两行...

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);