pit*_*zzo 1 post multithreading android server
我需要从我的服务器获取一些数据才能使我的应用程序正常工作。为了做到这一点,我将使用 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();
Run Code Online (Sandbox Code Playgroud)
我已经读到我可能会使用接口来存档它,但这是一个我还不太了解的概念。我想直接使用返回数据的方法,但据我所知,这是不可能的。你的时间!
编辑:根据 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);
}
Run Code Online (Sandbox Code Playgroud)
}
编辑:为 NoChinDeluxe 添加了例外:
03-24 17:38:09.072 13312-13312/com.pitazzo.geomoments E/AndroidRuntime:致命异常:主进程:com.pitazzo.geomoments,PID:13312 java.lang.NullPointerException:尝试调用接口方法.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(Native Method) 在 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)ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)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);
}
Run Code Online (Sandbox Code Playgroud)
}
实现此目的的最佳方法是使用 anHttpURLConnection在 an 内部进行 Web 调用AsyncTask,然后通过回调将结果传递回调用 Activity。以下是一些可帮助您入门的代码:
您应该了解的第一件事是如何正确使用带有AsyncTask. 下面是一个AsyncTask定义回调接口的例子:
import android.os.AsyncTask;
public class TestTask extends AsyncTask<String, Void, String> {
TestTaskCallback listener;
public TestTask(TestTaskCallback listener) {
this.listener = listener;
}
protected String doInBackground(String... args) {
String input = args[0];
String output = "simulated return value";
return output;
}
protected void onPostExecute(String result) {
listener.onResultReceived(result);
}
public interface TestTaskCallback {
void onResultReceived(String result);
}
}
Run Code Online (Sandbox Code Playgroud)
其工作方式是,您定义一个公共接口,然后在您的 Activity 中实现该接口。它充当“侦听器”,等待发送给它的任何数据。我们定义接口TestTaskCallback是因为我们将从我们的数据发送AsyncTask到我们的调用 Activity。
那么在Activity中,我们需要实现这个接口,并在创建任务的时候传入一个对我们实现的引用。这样,当任务触发时,它知道将结果发送到哪里,结果返回到我们的 Activity。示例实现可能如下所示:
public class TestActivity extends AppCompatActivity implements TestTask.TestTaskCallback {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
new TestTask(this).execute("Some input");
}
public void onResultReceived(String result) {
Log.d("TEST TASK RESULT", result);
}
}
Run Code Online (Sandbox Code Playgroud)
所以我们的 Activity 实现了我们在我们的 中定义的接口AsyncTask,并注意到我们AsyncTask获取了对这个实现的引用(通过构造函数传入)并在onPostExecute()方法中向它发送数据。这将允许您的结果发送到主 UI 线程,以便您可以适当地更新您的活动。
剩下的唯一事情就是实际拨打网络电话。我建议HttpURLConnection为此使用一个。您可以将此代码放在doInBackground()您的AsyncTask.
我将向您展示我设置的示例 Web 服务调用。这显示了如何进行 Web 服务调用以检索 JSON 响应。它看起来像这样:
//The JSON we will get back as a response from the server
JSONObject jsonResponse = null;
//Http connections and data streams
URL url;
HttpURLConnection httpURLConnection = null;
OutputStreamWriter outputStreamWriter = null;
try {
//open connection to the server
url = new URL("your_url_to_web_service");
httpURLConnection = (HttpURLConnection) url.openConnection();
//set request properties
httpURLConnection.setDoOutput(true); //defaults request method to POST
httpURLConnection.setDoInput(true); //allow input to this HttpURLConnection
httpURLConnection.setRequestProperty("Content-Type", "application/json"); //header params
httpURLConnection.setRequestProperty("Accept", "application/json"); //header params
httpURLConnection.setFixedLengthStreamingMode(jsonToSend.toString().getBytes().length); //header param "content-length"
//open output stream and POST our JSON data to server
outputStreamWriter = new OutputStreamWriter(httpURLConnection.getOutputStream());
outputStreamWriter.write(jsonToSend.toString());
outputStreamWriter.flush(); //flush the stream when we're finished writing to make sure all bytes get to their destination
//prepare input buffer and get the http response from server
StringBuilder stringBuilder = new StringBuilder();
int responseCode = httpURLConnection.getResponseCode();
//Check to make sure we got a valid status response from the server,
//then get the server JSON response if we did.
if(responseCode == HttpURLConnection.HTTP_OK) {
//read in each line of the response to the input buffer
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8"));
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close(); //close out the input stream
try {
//Copy the JSON response to a local JSONObject
jsonResponse = new JSONObject(stringBuilder.toString());
} catch (JSONException je) {
je.printStackTrace();
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if(httpURLConnection != null) {
httpURLConnection.disconnect(); //close out our http connection
}
if(outputStreamWriter != null) {
try {
outputStreamWriter.close(); //close our output stream
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
//Return the JSON response from the server.
return jsonResponse;
Run Code Online (Sandbox Code Playgroud)
这几乎就是你想要做的事情所需要知道的全部内容。我意识到这是一次性向您提供的大量信息,但是如果您花时间一点一点地研究它,您会发现这毕竟不是太难,而且实际上是一个非常强大的工具将一直使用编程 Android 应用程序!
希望这可以帮助。有任何不完全理解的部分,请随时提问!
| 归档时间: |
|
| 查看次数: |
8284 次 |
| 最近记录: |