I am trying to call a REST web service from my phone. I am using following code to complete this. I have only one activity which has a button and textview. Whenever i click on button it gives following error in logcat
:
AndroidRuntime :: at android.os.Handler.dispatchMessage(Handler.java:92)
What i am doing wrong? how can i solve this ???
Following are my classes.
rest.java
public class Rest extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_rest);
Button button = (Button) findViewById(R.id.btn);
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String url = "http://192.168.1.145/tst.php";
RestService re = new RestService();
JSONObject jb = RestService.doGet(url);
TextView tv = (TextView) findViewById(R.id.txtView);
tv.setText(jb.toString());
}
});
}
}
RestService.java
public class RestService {
public static JSONObject doGet(String url) {
JSONObject json = null;
HttpClient httpclient = new DefaultHttpClient();
// Prepare a request object
HttpGet httpget = new HttpGet(url);
// Accept JSON
httpget.addHeader("accept", "application/json");
// Execute the request
HttpResponse response;
try {
response = httpclient.execute(httpget);
// Get the response entity
// Log.e("myApp", "Issue is here...!");
HttpEntity entity = response.getEntity();
// If response entity is not null
if (entity != null) {
// get entity contents and convert it to string
InputStream instream = entity.getContent();
String result= convertStreamToString(instream);
// construct a JSON object with result
json=new JSONObject(result);
// Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Return the json
return json;
}
private static String convertStreamToString(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
Having tried the code that you posted, I get the following exception (which I suspect you'll find the same in logcat if you look)
12-17 10:28:26.850 2182-2182/com.example.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
at com.example.app.RestService.doGet(RestService.java:31)
at com.example.app.MainActivity$1.onClick(MainActivity.java:28)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
You get this because you're trying to do something across the network on the main thread, which is not allowed. (It's mentioned in the Google design guidelines here)
The best solution in this case would be to move the service call into an AsyncTask, which runs on a separate thread and doesn't block the UI.
Try this, I swapped out the URL for a freely available JSON web service that just returns the date
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String url = "http://date.jsontest.com";
new MyAsyncTask().execute(url);
}
});
}
class MyAsyncTask extends AsyncTask<String,Void,JSONObject> {
@Override
protected JSONObject doInBackground(String... urls) {
return RestService.doGet(urls[0]);
}
@Override
protected void onPostExecute(JSONObject jsonObject) {
TextView tv = (TextView) findViewById(R.id.txtView);
tv.setText(jsonObject.toString());
}
}
}
Write an async task and do the network operation in that thread.
public class myTask extends AsyncTask<String, JSONObject, Void> {
private ProgressDialog dialog;
private Context mContext;
public myTask(Context mContext){
this.mContext = mContext;
}
protected void onPreExecute() {
this.dialog = new ProgressDialog(mContext);
this.dialog.setCancelable(false);
this.dialog.setMessage("please wait..");
this.dialog.show();
}
protected JSONObject doInBackground(String... ids) {
String url = "http://192.168.1.145/tst.php";
RestService re = new RestService();
JSONObject jb = RestService.doGet(url);
return jb;
}
protected Void onPostExecute(JSONObject jb) {
//get json data and set
}
}