Неизвестная причина java .lang.RuntimeException - PullRequest
0 голосов
/ 13 марта 2020

Когда я пытался запустить свое приложение, которое проверяет что-то с базой данных, я столкнулся с иррациональной ошибкой. Мое приложение выдало java .lang.RuntimeException со строкой: OutputStream ops = http.getOutputStream();

Мой код:

 String result = "";
        String connstr = "http://myip:8080/androidlogin.php";

        try {
            URL url = new URL(connstr);
            HttpURLConnection http = (HttpURLConnection) url.openConnection();
            http.setRequestMethod("POST");
            http.setDoInput(true);
            http.setDoOutput(true);

Log.d("TAG", "1");
            OutputStream ops = http.getOutputStream();
            Log.d("TAG", "2");
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(ops,"UTF-8"));
            Log.d("TAG", "3");
            String data = URLEncoder.encode("user","UTF-8")+"="+URLEncoder.encode(id,"UTF-8");
            Log.d("TAG", "4");
            writer.write(data);
            writer.flush();
            writer.close();
            ops.close();

            InputStream ips = http.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(ips,"ISO-8859-1"));
            String line ="";
            while ((line = reader.readLine()) != null)
            {
                result += line;
            }
            reader.close();
            ips.close();
            http.disconnect();
            return result;

        } catch (MalformedURLException e) {
            result = e.getMessage();
        } catch (IOException e) {
            result = e.getMessage();
        }


        return result;

И моя ошибка выглядит так:

2020-03-13 08:01:07.460 10633-10633/com.hu.jam E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.hu.jam, PID: 10633
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hu.jam/com.hu.jam.MainActivity}: android.os.NetworkOnMainThreadException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2984)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
        at android.app.ActivityThread.-wrap14(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
     Caused by: android.os.NetworkOnMainThreadException

Самая интересная часть заключается в том, что между Log 1 и ошибкой есть три интересных сообщения в logcat:

2020-03-13 08:01:07.442 10633-10633/com.hu.jam D/TAG: 1
2020-03-13 08:01:07.444 10633-10633/com.hu.jam I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
2020-03-13 08:01:07.444 10633-10633/com.hu.jam I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
2020-03-13 08:01:07.451 10633-10633/com.hu.jam D/AndroidRuntime: Shutting down VM
2020-03-13 08:01:07.460 10633-10633/com.hu.jam E/AndroidRuntime: FATAL EXCEPTION: main

Вот скрипт php:

<?php
$db = "database1";
$user = $_POST["user"];
$host = "localhost";

$conn = mysqli_connect($host, "root", "", $db);
if($conn){
    echo "connected....!";
    $q= "select * from article where a_title='$user'";

    $result = mysqli_query($conn, $q);
    if(mysqli_num_rows($result) > 0){
        echo"login successfull...!";
    }else {
        echo"login failed....!";
    }

}else{
    echo"connection failed....!";
}


?>

Что проблема с моим кодом? Кажется, с этим все в порядке, но не работает ...

Ответы [ 3 ]

0 голосов
/ 13 марта 2020

Сначала создайте новый Runnable. Помните, он должен предоставить вам механизм для получения результата после завершения. Кроме того, я настоятельно призываю вас воспользоваться try-with-Resources оператором вместо явного закрытия. Что-то вроде

public class MyLoginRunnable implements Runnable {
    private StringBuilder sb = new StringBuilder();
    private String connstr;
    private String id;

    public MyLoginRunnable(String connstr, String id) {
        this.connstr = connstr;
        this.id = id;
    }

    public String getResult() {
        return sb.toString();
    }

    @Override
    public void run() {
        try {
            URL url = new URL(connstr);
            HttpURLConnection http = (HttpURLConnection) url.openConnection();
            http.setRequestMethod("POST");
            http.setDoInput(true);
            http.setDoOutput(true);

            try (OutputStream ops = http.getOutputStream();
                    BufferedWriter writer = new BufferedWriter( //
                            new OutputStreamWriter(ops, "UTF-8"))) {
                String data = URLEncoder.encode("user", "UTF-8") //
                        + "=" + URLEncoder.encode(id, "UTF-8");
                writer.write(data);
            }

            try (InputStream ips = http.getInputStream();
                    BufferedReader reader = new BufferedReader( //
                            new InputStreamReader(ips, "ISO-8859-1"))) {
                String line = "";
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append(System.lineSeparator());
                }
            }
            http.disconnect();
        } catch (MalformedURLException e) {
            sb.append(e.getMessage());
        } catch (IOException e) {
            sb.append(e.getMessage());
        }
    }
}

Тогда вы можете использовать его как

String connstr = "http://myip:8080/androidlogin.php";
MyLoginRunnable mlr = new MyLoginRunnable(connstr, "");
Thread t = new Thread(mlr);
t.start();
try {
    t.join(); // <-- this is for your simple example, in real code you don't want to pause
} catch (InterruptedException e) {
    e.printStackTrace();
}
String result = mlr.getResult();
0 голосов
/ 13 марта 2020

Исключением является то, что вы запускаете сетевую задачу, которая должна быть фоновой, в основном потоке пользовательского интерфейса. Используйте AsyncTask для сетевых задач или задач ввода-вывода. https://developer.android.com/reference/android/os/AsyncTask

0 голосов
/ 13 марта 2020

Для работы с сетевыми запросами рекомендуется запускать код в отдельном потоке Как запустить поток Runnable в Android через определенные интервалы?

Runnable r = new Runnable() {
    public void run() {
      //Put your network code here
    }
}.start();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...