【发布时间】:2016-07-10 01:17:15
【问题描述】:
我需要从我的服务器获取一些数据才能使我的应用正常运行。为此,我将使用 POST。据我所知,我必须在一个不能作为主线程的线程中请求数据。我发现将接收到的数据放入 UI 线程中定义的变量中有点困难。所以,我的问题是,这是最好的方法吗? 例如,在我的主要活动中使用在 AsyncTask 中调用的 setter 来设置定义的变量的值是否正确?或者这个选项可能更好?
Thread nt = new Thread(){
@Override
public void run(){
try{
//get data with POST and then something like main.setValue(data);
}catch(Exception e){
e.printStackTrace();
}
}
};
nt.start();
我已经读到我可能会使用接口来存档它,但这是一个我还不太了解的概念。我想直接使用返回数据的方法,但据我所知,这是不可能的。 谢谢你的时间!
编辑:根据 NoChinDeluxe 答案的新代码:
public class LoginHandler {
public static class Login extends AsyncTask<String, String, Integer> {
LoginCallback listener;
@Override
protected Integer doInBackground(String... params) {
URL url;
postDataParams.put("name", params[0]);
HashMap<String, String> postDataParams = new HashMap<String, String>();
postDataParams.put("password", params[1]);
try {
url = new URL("http://mashiron.xyz/_03z/gmpia/proc.php");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(HttpHandler.getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
System.out.println("Respuesta: "+conn.getResponseCode());
return conn.getResponseCode();
} catch (Exception e) {
e.printStackTrace();
return 404;
}
}
protected void onPostExecute(int result){
System.out.println("Respuesta 2: "+result);
listener.onResultReceived(result);
}
}
public interface LoginCallback {
void onResultReceived(int result);
}
}
编辑:为 NoChinDeluxe 添加了例外:
03-24 17:38:09.072 13312-13312/com.pitazzo.geomoments E/AndroidRuntime: 致命异常: main 进程:com.pitazzo.geomoments,PID:13312 java.lang.NullPointerException:尝试在空对象引用上调用接口方法“void com.pitazzo.geomoments.Handlers.LoginHandler$LoginCallback.onResultReceived(int)” 在 com.pitazzo.geomoments.Handlers.LoginHandler$Login.onPostExecute(LoginHandler.java:65) 在 com.pitazzo.geomoments.Handlers.LoginHandler$Login.onPostExecute(LoginHandler.java:17) 在 android.os.AsyncTask.finish(AsyncTask.java:636) 在 android.os.AsyncTask.access$500(AsyncTask.java:177) 在 android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:135) 在 android.app.ActivityThread.main(ActivityThread.java:5300) 在 java.lang.reflect.Method.invoke(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
编辑:NoChainDeluxe 的更多代码
public class LoginActivity extends AppCompatActivity implements LoginHandler.LoginCallback{
EditText name;
EditText password;
Button login;
int code;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
/*
if(logueado){
}
*/
name = (EditText) findViewById(R.id.loginuser);
password = (EditText) findViewById(R.id.loginpassword);
login = (Button) findViewById(R.id.loginlogin);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String params[] = {name.getText().toString(), password.getText().toString()};
System.out.println("Params: "+params.toString());
new LoginHandler.Login().execute(params);
System.out.println("Respuesta 4: "+code);
if(code == 200){
Toast toast1 =
Toast.makeText(getApplicationContext(),
"Iniciado sesión", Toast.LENGTH_SHORT);
toast1.show();
}else{
Toast toast1 =
Toast.makeText(getApplicationContext(),
"Nombre de usuario y/o contraseña incorrectos: "+code, Toast.LENGTH_SHORT);
toast1.show();
}
}
});
}
public void onResultReceived(int resultado) {
code = resultado;
System.out.println("Respuesta 3: "+code);
}
}
【问题讨论】:
-
根据您的需要使用 AysncTask。如果您使用它,则不需要任何 setter。在 AsyncTask 的 onPostExecute() 方法中,你可以更新你的 UI。
标签: android multithreading post server