gpt4 book ai didi

android - 从服务器请求数据的最佳方式

转载 作者:行者123 更新时间:2023-11-29 15:06:58 25 4
gpt4 key购买 nike

我需要从我的服务器获取一些数据以使我的应用正常运行。为此,我将使用 POST。据我所知,我必须在不能成为主线程的线程中请求该数据。我发现将接收到的数据放入 UI 线程中定义的变量中有点困难。那么,我的问题是,哪种方法最好?

设置变量的值是否正确,例如,在我的主要 Activity 中,使用在 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();

我读到过我可以使用接口(interface)来存档它,但我对这个概念还不是很了解。我想直接使用返回数据的方法,但据我所知,这是不可能的。

编辑:根据 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 添加异常(exception):

03-24 17:38:09.072 13312-13312/com.pitazzo.geomoments E/AndroidRuntime:致命异常:主要过程:com.pitazzo.geomoments,PID:13312java.lang.NullPointerException:尝试在空对象引用上调用接口(interface)方法“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( native 方法)在 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);

}

}

最佳答案

实现此目的的最佳方法是使用 HttpURLConnectionAsyncTask 中进行网络调用,然后通过回调将结果传回调用 Activity。下面是一些可帮助您入门的代码:

您应该了解的第一件事是如何正确使用带有 AsyncTask 的回调。下面是一个定义回调接口(interface)的 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);
}
}

其工作方式是,您定义一个公共(public)接口(interface),然后在您的 Activity 中实现该接口(interface)。这充当等待发送给它的任何数据的“监听器”。我们定义接口(interface) TestTaskCallback 因为我们要将我们的数据从我们的 AsyncTask 发送到我们调用的 Activity。

那么在Activity中,我们需要实现这个接口(interface),在创建task的时候传入一个我们实现的引用给task。这样,当任务触发时,它知道将结果发送到哪里,结果返回到我们的 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);
}
}

所以我们的 Activity 实现了我们在 AsyncTask 中定义的接口(interface),请注意我们的 AsyncTask 引用了这个实现(通过构造函数传入)并发送在 onPostExecute() 方法中将数据传递给它。这将允许您的结果被发送到主 UI 线程,以便您可以适本地更新您的 Activity。

剩下的唯一事情就是实际进行网络调用。为此,我建议使用 HttpURLConnection。您可以将此代码放入 AsyncTaskdoInBackground() 方法中。

我将向您展示我设置的网络服务调用示例。这显示了如何调用 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;

这几乎是您真正想要做的事情所需知道的全部内容。我意识到这是一次性向您抛出的大量信息,但如果您花时间一点一点地研究它,您会发现它毕竟不是太难,而且实际上是一个非常强大的工具,您可以您将一直使用 Android 应用程序编程!

希望这对您有所帮助。对于您尚未完全理解的任何部分,请随时提出问题!

关于android - 从服务器请求数据的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36166476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com