Android RESTful client

2019-04-11 03:24发布

问题:

I have a RESTful web service and I want to access it from Android.

public class AndroidClientActivity extends Activity {

private EditText text;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    text = (EditText) findViewById(R.id.editText1);
}

public void myClickHandler(View view){
    switch (view.getId()) {
    case R.id.button1:
        MyClient c = new MyClient();
        c.execute(text);
        break;
    }

}
}


public class MyClient extends AsyncTask<EditText, Integer, String> {

protected String doInBackground(EditText... strings) {

        WebResource wbr;
        Client client = Client.create();
        wbr = client.resource("http://my.ip.address:8080/MazeService/rest/service/hello");  
        String result = wbr.queryParam("number", "10").accept(MediaType.APPLICATION_JSON).get(String.class);
        strings[0].setText(result);
    return result;
}

protected void onProgressUpdate(Integer... progress) {
}

protected void onPostExecute(Long result) {
}
}

I get this stacktrace in LogCat:

02-09 00:06:38.593: E/AndroidRuntime(795): Caused by: java.lang.NullPointerException
02-09 00:06:38.593: E/AndroidRuntime(795):  at javax.ws.rs.core.MediaType.valueOf(MediaType.java:119)
02-09 00:06:38.593: E/AndroidRuntime(795):  at com.sun.jersey.api.client.ClientResponse.getType(ClientResponse.java:615)
02-09 00:06:38.593: E/AndroidRuntime(795):  at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:532)
02-09 00:06:38.593: E/AndroidRuntime(795):  at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506)
02-09 00:06:38.593: E/AndroidRuntime(795):  at com.sun.jersey.api.client.WebResource.handle(WebResource.java:674)
02-09 00:06:38.593: E/AndroidRuntime(795):  at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
02-09 00:06:38.593: E/AndroidRuntime(795):  at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:503)
02-09 00:06:38.593: E/AndroidRuntime(795):  at com.maze.client.MyClient.doInBackground(MyClient.java:19)
02-09 00:06:38.593: E/AndroidRuntime(795):  at com.maze.client.MyClient.doInBackground(MyClient.java:1)
02-09 00:06:38.593: E/AndroidRuntime(795):  at android.os.AsyncTask$2.call(AsyncTask.java:264)
02-09 00:06:38.593: E/AndroidRuntime(795):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-09 00:06:38.593: E/AndroidRuntime(795):  ... 5 more

Where is the problem?

回答1:

I think you are trying to access the UI thread from the doInBackground method and it's not a good place to do that instead change the text in onPostExecute method like this you can access the ui thread safely like this

first define you AsyncTask class as a private class in your Activity class

private class MyClient extends AsyncTask<EditText, Void, String> { 

protected String doInBackground(EditText... strings) {

        WebResource wbr;
        Client client = Client.create();
        wbr = client.resource("http://my.ip.address:8080/MazeService/rest/service/hello");  
        String result = wbr.queryParam("number", "10").accept(MediaType.APPLICATION_JSON).get(String.class);

    return result;
}
    protected void onPostExecute(String result) {
    if(result != null)
    text.setText(result);

    }
}

then access the UI thread from the onPostExecute

note that you are defining a Long parameter for the onPostExecute and thats wrong since you define it to take a String class in your AsyncTask definition



回答2:

Never use AsynTask to perform network request or whatever that need to be persisted. Async Task are strongly tied to your activity and if the user change the orientation of the screen since the App is re created the AsyncTask will be stopped.

I suggest you to use Service pattern with Intent Service and ResultReceiver. Take a look to RESTDroid. It's a library that allows you to perform any kind of REST request asynchronously and notify your UI with Request Listeners implementing the Virgil Dobjanschi's service pattern.



标签: android rest