在Android中实现线程不起作用

时间:2015-08-31 14:55:10

标签: java android mysql multithreading

我正在Android中编写一个基本应用程序,应用程序将通过PHP中的任务连接到MySql服务器,在Android Internet连接中必须在不同的线程中进行,所以我创建了实现Runnable接口的类。

package com.company.opax.loginmysql;

import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

/**
 * Created by opax on 30.08.2015.
 */

public class HttpPostMethod implements Runnable{
    private String fileInHost;
    private ArrayList<PostParameters> postParameterses;
    private StringBuffer postResult;

    public HttpPostMethod(String fileInHost, ArrayList<PostParameters> postParameterses){
        this.fileInHost = fileInHost;
        this.postParameterses = new ArrayList<PostParameters>(postParameterses);
    }

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

    @Override
    public void run() {
        try {
            String urlParameters = generateParameters();
            URLConnection conn = initializeUrlConnection();

            OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
            writer.write(urlParameters);
            writer.flush();

            String line;
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

            while ((line = reader.readLine()) != null) {
                postResult.append(line);
            }

            writer.close();
            reader.close();
        } catch (IOException e) {
            Log.e("Exception", this.getClass().getName() + " name: " + e.toString());
        }
    }

    private URLConnection initializeUrlConnection() throws MalformedURLException {
        URL url = new URL(fileInHost);
        URLConnection conn;

        try {
            conn = url.openConnection();
            conn.setDoOutput(true);
        }catch(IOException e){
            throw new MalformedURLException();
        }

        return conn;
    }

    private String generateParameters(){
        StringBuffer finishPostQuery = new StringBuffer();

        for(PostParameters p : postParameterses){
            finishPostQuery.append(p.getNameParam());
            finishPostQuery.append("=");
            finishPostQuery.append(p.getValueParam());
            finishPostQuery.append("&");
        }

        if(!finishPostQuery.toString().equals("login=seba&password=pass&"))
            throw new AssertionError("blad generatora zapytania: " + finishPostQuery);

        return finishPostQuery.toString();
    }
}

登录类

public class Login {
    private User user;
    private final String paramLogin = "login";
    private final String paramPass = "password";

    public Login(User user){
        this.user = user;
    }

    public boolean tryLogin(){
        try{
            ArrayList<PostParameters> postParameterses = new ArrayList<>();
            postParameterses.add(new PostParameters(paramLogin, user.getUserName()));
            postParameterses.add(new PostParameters(paramPass, user.getUserPass()));

            HttpPostMethod httpPostMethod = new HttpPostMethod("http://blaba.php", postParameterses);
            httpPostMethod.run();
            Log.i("bla", httpPostMethod.getResult());

        } catch (Exception e) {
            Log.i("Exception", e.toString());
        }
        return false;
    }
}

我正在尝试连接其他线程,但我仍然有一个错误:'android.os.NetworkOnMainThreadException' 我很感激所有的建议我做错了。

2 个答案:

答案 0 :(得分:1)

而不是:

httpPostMethod.run();

做的:

new Thread(httpPostMethod).start();

如果由于某些原因(超时,错误登录)导致您的登录调用失败,您应该以某种方式向用户报告 - 这就是AsyncTask类的用途。它允许您在doInBackkground中运行后台代码,并在网络操作结束后 - 在onPostExecute中,您可以执行与UI相关的内容 - 例如显示错误/结果。

答案 1 :(得分:1)

我建议你做两件事。 首先使用AsyncTask而不是纯Java线程。

但主要的建议是使用一个发出http请求的库。 我喜欢使用Retrofit,它可以为你处理所有请求和线程部分,但还有其他部分。