2012-02-09 212 views
3

我有一個REST風格的Web服務,我想從Android訪問它。Android RESTful客戶端

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) { 
} 
} 

我在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 

問題出在哪裏?

+0

將'result'放入類專用字段中,並更新'onPostExecute'方法中的EditBox。 – 2012-02-09 02:09:09

回答

4

我認爲你正試圖從doInBackground方法訪問UI線程,它不這樣做,而不是改變文本的onPostExecute方法這樣你就可以安全地訪問UI線程這樣

第一的好地方定義你的AsyncTask類作爲一個私有類在你的Activity類

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

    } 
} 

然後從你定義的onPostExecute

注訪問UI線程因爲你定義它採取String類在你的AsyncTask定義

+0

好的,現在我有另一個問題了:'在設備'emulator-5554上安裝AndroidClient.apk失敗!'爲什麼?它根本不會啓動AVD ... – Dragos 2012-02-09 10:46:01

+0

請考慮發佈新問題 – confucius 2012-02-09 10:47:11

0

切勿使用AsynTask執行網絡請求或什麼是需要被保留Long參數爲onPostExecute並且那是錯誤的。異步任務與您的活動緊密相關,並且如果用戶在創建應用程序後更改屏幕的方向,則AsyncTask將會停止。

我建議你在Intent Service和ResultReceiver中使用Service模式。看看RESTDroid。它是一個庫,允許您異步執行任何類型的REST請求,並通過實現Virgil Dobjanschi服務模式的請求偵聽器來通知您的UI。