无法调用REST API的机器人 [英] Unable to call REST API in android
问题描述
我想从我的手机拨打一个REST Web服务。我使用下面的code来完成这一点。我只有一个活动有一个按钮和TextView的。每当我点击按钮,它提供了以下错误的logcat
:
AndroidRuntime ::在android.os.Handler.dispatchMessage(Handler.java:92)
我在做什么错了?我怎样才能解决这个问题??? 以下是我的课。
rest.java
公共类休息延伸活动{
@覆盖
保护无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.start_rest);
Button按钮=(按钮)findViewById(R.id.btn);
button.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
// TODO自动生成方法存根
字符串URL =http://192.168.1.145/tst.php;
RestService重=新RestService();
JSONObject的JB = RestService.doGet(URL);
TextView的电视=(TextView中)findViewById(R.id.txtView);
tv.setText(jb.toString());
}
});
}
}
RestService.java
公共类RestService {
公共静态的JSONObject的doGet(字符串URL){
JSONObject的JSON = NULL;
HttpClient的HttpClient的=新DefaultHttpClient();
// prepare请求对象
HTTPGET HTTPGET =新HTTPGET(URL);
//接受JSON
httpget.addHeader(接受,应用/ JSON);
//执行请求
HTT presponse响应;
尝试 {
响应= httpclient.execute(HTTPGET);
//获取响应实体
// Log.e(对myApp,问题就在这里...!);
HttpEntity实体= response.getEntity();
//如果响应实体不为空
如果(实体!= NULL){
//获取实体内容,并将其转换为字符串
InputStream的河道= entity.getContent();
字符串结果= convertStreamToString(河道);
//构建与结果的JSON对象
JSON =新的JSONObject的(结果);
//关闭输入流会触发连接释放
instream.close();
}
}赶上(ClientProtocolException E){
// TODO自动生成的catch块
e.printStackTrace();
}赶上(IOException异常E){
// TODO自动生成的catch块
e.printStackTrace();
}赶上(JSONException E){
// TODO自动生成的catch块
e.printStackTrace();
}
//返回JSON
返回JSON;
}
私有静态字符串convertStreamToString(InputStream的是){
的BufferedReader BR = NULL;
StringBuilder的SB =新的StringBuilder();
串线;
尝试 {
BR =新的BufferedReader(新InputStreamReader的(是));
而((行= br.readLine())!= NULL){
sb.append(线);
}
}赶上(IOException异常E){
e.printStackTrace();
} 最后 {
如果(BR!= NULL){
尝试 {
br.close();
}赶上(IOException异常E){
e.printStackTrace();
}
}
}
返回sb.toString();
}
}
尝试过,你贴在code,我得到下面的异常(我怀疑你会发现同样的logcat的,如果你看一下)
10月12日至17日:28:26.850 2182年至2182年/ com.example.app E / AndroidRuntime:致命异常:主要
android.os.NetworkOnMainThreadException
在android.os.StrictMode $ AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
在java.net.InetAddress.lookupHostByName(InetAddress.java:385)
在java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
在java.net.InetAddress.getAllByName(InetAddress.java:214)
在org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
在org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
在org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
在org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
在org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
在org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
在org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
在com.example.app.RestService.doGet(RestService.java:31)
在com.example.app.MainActivity $ 1.onClick(MainActivity.java:28)
在android.view.View.performClick(View.java:4084)
在android.view.View $ PerformClick.run(View.java:16966)
在android.os.Handler.handleCallback(Handler.java:615)
在android.os.Handler.dispatchMessage(Handler.java:92)
在android.os.Looper.loop(Looper.java:137)
在android.app.ActivityThread.main(ActivityThread.java:4745)
在java.lang.reflect.Method.invokeNative(本机方法)
在java.lang.reflect.Method.invoke(Method.java:511)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:786)
在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
在dalvik.system.NativeStart.main(本机方法)
您得到这个,因为你正在试图做整个网络的东西为主线,这是不允许的。 (它提到在谷歌设计指南这里)
在这种情况下,最好的解决办法是,移动服务呼叫到一个 AsyncTask的,它运行在一个单独的线程,并不会阻止用户界面。
试试这个,我换了网址为免费提供的JSON Web服务刚刚返回日期
公共类MainActivity延伸活动{
@覆盖
保护无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_main);
Button按钮=(按钮)findViewById(R.id.btn);
button.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
字符串URL =http://date.jsontest.com;
新MyAsyncTask()执行(URL);
}
});
}
类MyAsyncTask扩展的AsyncTask<字符串,无效的JSONObject> {
@覆盖
受保护的JSONObject doInBackground(字符串...网址){
返回RestService.doGet(网址[0]);
}
@覆盖
保护无效onPostExecute(的JSONObject的JSONObject){
TextView的电视=(TextView中)findViewById(R.id.txtView);
tv.setText(jsonObject.toString());
}
}
}
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());
}
}
}
这篇关于无法调用REST API的机器人的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!