【问题标题】:Http Data Request(app crashes)Http 数据请求(应用程序崩溃)
【发布时间】:2015-09-13 19:34:29
【问题描述】:

我是 Andriod 编程的初学者,我使用 android Studio,但我在网上看到了一个使用 Eclipse 的 Http 教程,我在 Android Studio 中解释得最好,该应用程序有一个 HttpManager 类,它返回如下所示的 json 数据

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class HttpManager {


    public static String getData(String uri) throws IOException {
        StringBuilder sb=new StringBuilder();
        BufferedReader reader= null;

        try {
            URL url = new URL(uri);
            HttpURLConnection con= (HttpURLConnection) url.openConnection();
            reader= new BufferedReader(new InputStreamReader(con.getInputStream()));

            String line;
          while ((line=reader.readLine()) !=null) {

              sb.append(line+ "\n");

          }


        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        finally {
            if(reader != null){
                reader.close();
            }
        }

        return sb.toString();
    }


}

主要活动,特别是 doInbackground 方法应该获取此 json 数据并显示它,但应用程序在下面的 onPrexecute 方法代码后崩溃

 import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.support.v4.os.AsyncTaskCompat;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.security.Policy;
import java.util.Objects;

public class MainActivity extends AppCompatActivity {
    TextView output;
    ProgressBar pb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        output=(TextView) findViewById(R.id.textView);
        output.setMovementMethod(new ScrollingMovementMethod());
        pb= (ProgressBar) findViewById(R.id.progressBar);
        pb.setVisibility(View.INVISIBLE);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will

        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            if (isOnline()){
                requestData("http://localhost/database/getInfodroid.php");
            }
            else {
                Toast.makeText(this,"Network Unavailable",Toast.LENGTH_LONG).show();
            }

            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void requestData(String uri) {
        MyTask task = new MyTask();
        task.execute(uri);
    }

    protected void updateDisplay(String message){
        output.append(message +"\n");

    }

   protected boolean isOnline(){
       ConnectivityManager cm= (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
       NetworkInfo netinfo= cm.getActiveNetworkInfo();
       if(netinfo!= null && netinfo.isConnectedOrConnecting()){
           return true;
       }
       else {
           return false;
       }



   }


    private class MyTask extends AsyncTask {

        @Override
        protected void onPreExecute() {
            updateDisplay("Background Task Started");
            pb.setVisibility(View.VISIBLE);
        }


        @Override
        protected Object doInBackground(Object[] objects) {

            try {
                String content =HttpManager.getData(objects[0].toString());
                return content;
            } catch (IOException e) {
                e.printStackTrace();
            }


            return "Task Complete";
        }

        @Override
        protected void onPostExecute(Object o) {
           updateDisplay(o.toString());
            pb.setVisibility(View.INVISIBLE);
        }


        @Override
        protected void onProgressUpdate(Object[] values) {
            updateDisplay(values[0].toString());
        }
    }



}

我再说一遍,我很新,我在 Android Studio 中尽我所能解释它在 eclipse 中略有不同,设置所有权限

从本地主机更改为 IP 地址后,应用程序确实崩溃了,但我现在得到以下异常 LOGCAT:

10-03 14:13:21.876 2126-9411/? W/System.err: java.net.ConnectException: failed to connect to localhost/127.0.0.1 (port 80): connect failed: ECONNREFUSED (Connection refused)
10-03 14:13:21.877 2126-9411/? W/System.err:     at libcore.io.IoBridge.connect(IoBridge.java:124)
10-03 14:13:21.877 2126-9411/? W/System.err:     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
10-03 14:13:21.877 2126-9411/? W/System.err:     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:452)
10-03 14:13:21.877 2126-9411/? W/System.err:     at java.net.Socket.connect(Socket.java:884)
10-03 14:13:21.877 2126-9411/? W/System.err:     at com.android.okhttp.internal.Platform.connectSocket(Platform.java:117)
10-03 14:13:21.877 2126-9411/? W/System.err:     at com.android.okhttp.internal.http.SocketConnector.connectRawSocket(SocketConnector.java:160)
10-03 14:13:21.877 2126-9411/? W/System.err:     at com.android.okhttp.internal.http.SocketConnector.connectCleartext(SocketConnector.java:67)
10-03 14:13:21.877 2126-9411/? W/System.err:     at com.android.okhttp.Connection.connect(Connection.java:152)
10-03 14:13:21.877 2126-9411/? W/System.err:     at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
10-03 14:13:21.877 2126-9411/? W/System.err:     at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
10-03 14:13:21.877 2126-9411/? W/System.err:     at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
10-03 14:13:21.877 2126-9411/? W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
10-03 14:13:21.878 2126-9411/? W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
10-03 14:13:21.878 2126-9411/? W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
10-03 14:13:21.878 2126-9411/? W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
10-03 14:13:21.878 2126-9411/? W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
10-03 14:13:21.878 2126-9411/? W/System.err:     at hilz.myapplication.HttpManager.getData(HttpManager.java:22)
10-03 14:13:21.878 2126-9411/? W/System.err:     at hilz.myapplication.MainActivity$MyTask.doInBackground(MainActivity.java:118)
10-03 14:13:21.884 2126-9411/? W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:295)
10-03 14:13:21.884 2126-9411/? W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-03 14:13:21.901 2126-9411/? W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
10-03 14:13:21.901 2126-9411/? W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
10-03 14:13:21.901 2126-9411/? W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
10-03 14:13:21.902 2126-9411/? W/System.err:     at java.lang.Thread.run(Thread.java:818)
10-03 14:13:21.902 2126-9411/? W/System.err: Caused by: android.system.ErrnoException: connect failed: ECONNREFUSED (Connection refused)
10-03 14:13:21.902 2126-9411/? W/System.err:     at libcore.io.Posix.connect(Native Method)
10-03 14:13:21.906 2126-9411/? W/System.err:     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:111)
10-03 14:13:21.906 2126-9411/? W/System.err:     at libcore.io.IoBridge.connectErrno(IoBridge.java:137)
10-03 14:13:21.908 2126-9411/? W/System.err:     at libcore.io.IoBridge.connect(IoBridge.java:122)
10-03 14:13:21.908 2126-9411/? W/System.err:    ... 23 more

【问题讨论】:

  • 您能否发布您的 logcat 输出,以便我们知道是什么引发了错误?
  • localhost/database/getInfodroid.php -> 我不认为你想要本地主机,因为它将是设备本地主机而不是你的 PC。我打赌您需要将 localhost 更改为服务器的 IP 地址。
  • 我该如何解决它现在似乎无法连接到服务器但应用程序确实崩溃了

标签: android http android-asynctask


【解决方案1】:

在 onPostExecute 中接收到的对象为 null,调用你的 updateDisplay(...) 它会抛出 NPE。

我建议您将“内容”保存为属性并在您的 postExecute 方法中检索值。

我建议您在尝试更新不在您的主线程中的 UI 时要小心(postexecute 发生在后台任务之后)。

看看:

private class MyTask extends AsyncTask {

private Activity activity;
private String content;

public MyTask(Activity activity){this.activity = activity;}

 @Override
 protected void onPreExecute() {
   updateDisplay("Background Task Started");
   pb.setVisibility(View.VISIBLE);
 }

 @Override
 protected Object doInBackground(Object[] objects) {
   try {
       content =HttpManager.getData(objects[0].toString());
       return content;
   } catch (IOException e) {
     e.printStackTrace();
   }
   return "Task Complete";
 }

  @Override
  protected void onPostExecute(Object o) {
    activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            updateDisplay(content);
            pb.setVisibility(View.INVISIBLE);     
        }
    });    

 }

 @Override
 protected void onProgressUpdate(Object[] values) {
    activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
          updateDisplay(values[0].toString());
        }
    });  
 }
}

希望对你有帮助。

【讨论】:

  • 这个答案是我的第一个猜测,因为我没有你的堆栈跟踪...我通常指定在主线程上运行以防有任何疑问
  • 这不是我的问题,我只是想让你知道。但是,是的,没有他的堆栈跟踪就很难说
  • 你会发现这个组件很有趣,可以用来生成 httpRequests:github.com/juaagugui/AndroidHttpRestService。它易于学习和使用。这是我的,我将它添加到我的所有项目中
  • 哎呀,对不起@user1282637。在西班牙这里为时已晚,无法正确阅读。 :P
  • 好的,谢谢大家会在我获得更好的互联网连接后发布日志猫我也会听从你的建议,我会在明天晚上给你反馈
【解决方案2】:

在 stackoverflow 上找到了我正在寻找的内容,显然我应该使用 10.0.2.2 而不是在我的 url 代码中使用 localhost

【讨论】:

    【解决方案3】:

    10.0.2.2 是模拟器的本地主机,这意味着如果您的 PC 上有运行模拟器的测试服务器。如果不是这种情况,它将无法解决您的问题。如果您很确定它是 IP,我会探索您的网络选项并获取您的 PC 的 IP。将 IP 设置为服务器的 IP 还可以让您从设备上进行 USB 测试,而不仅仅是模拟器。

    查看代码,如果您将数据从应用程序发送到服务器,我看不到已声明的方法 (POST/GET)。您发送的 URL 中也没有参数,因此除非特定页面已编码对象供您返回,否则您将收到另一个错误。

    这是我用来连接服务器的示例脚本

    public class CCJson {
    
        // left blank to aviod calls to this constructor
        public CCJson(){}
        // place your IP in place of the ip
        public static String url = "http://102.0.0.1/appActions.php";
    
    
        public static JSONObject performPostCallObj( String params) throws MalformedURLException {
    
            URL defURL = new URL(url);
            JSONObject response=null;
            try {
    
    
                HttpURLConnection conn = (HttpURLConnection) defURL.openConnection();
                conn.setRequestMethod("POST");
                conn.setDoOutput(true);
    
                OutputStreamWriter wr = new OutputStreamWriter( conn.getOutputStream());
                wr.write(params);
                wr.flush();
                wr.close();
    
                String line;
                StringBuilder sb= new StringBuilder();
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
                while ((line=br.readLine()) != null) {
                    sb.append(line);
                    response =new JSONObject(sb.toString());
                }
                br.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return response;
        }
    

    我从 AsyncTask 调用此代码,它返回一个 JSONObject

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-23
      • 2014-01-30
      • 1970-01-01
      • 2017-10-30
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      相关资源
      最近更新 更多