[英]onPostExecute retrieves null from server
我嘗試使用AsyncTask從服務器讀取數據,但是當我將參數提供給onPostExecute時,它將檢索到我為null.MainActivity類:
public class MainActivity extends Activity{
EditText name, password;
Button login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = (EditText) findViewById(R.id.name);
password = (EditText) findViewById(R.id.password);
login = (Button) findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView uiUpdate = (TextView) findViewById(R.id.output);
String outputasync = uiUpdate.getText().toString();
String serverURL = "http://192.168.1.105/myapp/text.php";
LongOperation longOperation = new LongOperation(MainActivity.this);
longOperation.execute(serverURL);
longOperation.onPostExecute(uiUpdate);
}
});
}
AsyncTask:
public class LongOperation extends AsyncTask<String, Void, String> {
private Context mcontext;
private String content;
private String error = null;
AlertDialog alertDialog;
public LongOperation(Context context){
mcontext = context ;
}
@Override
protected void onPreExecute() {
alertDialog = new AlertDialog.Builder(mcontext).create();
alertDialog.setTitle("Login Information....");
}
@Override
protected String doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection client = (HttpURLConnection)url.openConnection();
client.connect();
InputStream inputStream = client.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
content = bufferedReader.readLine();
bufferedReader.close();
inputStream.close();
client.disconnect();
} catch (IOException e) {
error = e.getMessage();
}
return null;
}
protected void onPostExecute(TextView unused) {
alertDialog.dismiss();
if (error != null) {
unused.setText("Output : " + error);
} else {
unused.setText("Output : "+ content);
}
}
}
與服務器的連接正確,問題是在TextView中顯示服務器內部的消息。
就像安德魯霍里克所說:
您不應該從代碼中手動調用onPostExecute。 在asynctask上調用execute就足夠了。 當asynctask完成工作時,會自動調用onPostExecute。
並將onPostExecute參數更改為String
為了檢索帶有服務器消息的TextView,我做了Sharj所說的:
2)如何設置您的Activity中的TextView。 最簡單的方法是將活動變量傳遞給LongOperation構造函數,並使用它在onPostExecute中訪問TextView。
AsyncTask:
public class LongOperation extends AsyncTask<String, Void, String> {
TextView textviews;
private Context mcontext;
private String content;
private String error = null;
AlertDialog alertDialog;
public LongOperation(Context context, TextView textView){
textviews = textView;
mcontext = context ;
}
@Override
protected void onPreExecute() {
alertDialog = new AlertDialog.Builder(mcontext).create();
alertDialog.setTitle("Login Information....");
}
@Override
protected String doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection client = (HttpURLConnection)url.openConnection();
client.connect();
InputStream inputStream = client.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
content = bufferedReader.readLine();
bufferedReader.close();
inputStream.close();
client.disconnect();
} catch (IOException e) {
error = e.getMessage();
}
return null;
}
@Override
protected void onPostExecute(String unused) {
alertDialog.dismiss();
if (error != null) {
unused=("Output : " + error);
textviews.setText(unused);
} else {
unused=("Output : "+ content);
textviews.setText(unused);
}
}
MainActivity類:
public class MainActivity extends Activity{
EditText name, password;
Button login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = (EditText) findViewById(R.id.name);
password = (EditText) findViewById(R.id.password);
login = (Button) findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView uiUpdate = (TextView) findViewById(R.id.output);
String outputasync = uiUpdate.getText().toString();
String serverURL = "http://192.168.1.105/myapp/text.php";
LongOperation longOperation = new LongOperation(MainActivity.this, uiUpdate);
longOperation.execute(serverURL, outputasync);
}
});
}
注意:doInBackground仍可與“ return = null”一起使用,因為我只是用它來讀取服務器內部的數據,而不是在任何地方檢索它。
您不應該從代碼中手動調用onPostExecute
。 在asynctask上調用execute
就足夠了。 onPostExecute
時的AsyncTask完成其工作將自動被調用。
您的doInBackground()
方法僅返回null。 永遠。
未調用您的onPostExecute()
方法,因為它沒有覆蓋AsyncTask
的onPostExecute()
方法,該方法將使用String
參數
首先關於您的活動中的問題:
LongOperation longOperation = new LongOperation(MainActivity.this);
longOperation.execute(serverURL);
longOperation.onPostExecute(uiUpdate);
longOperation.execute(serverURL);
是一種異步方法。 這意味着您的程序將調用longOperation.onPostExecute(uiUpdate);
在執行方法之后,無需等待doInBackground
的結果。
你不能那樣做,你不應該那樣做。 onPostExecute
后自動調用doInBackground
返回結果(你返回null
現在。)
LongOperation longOperation =新的LongOperation(MainActivity.this); longOperation.execute(serverURL使用); longOperation.onPostExecute(uiUpdate);
現在的解決方案:
1) doInBackground
返回類型應始終等於onPostExecute
參數。
如果返回String,則onPostExecute
將如下所示:
protected void onPostExecute(String string) {
}
2)如何設置您Activity
TextView
。 最簡單的方法是將活動變量傳遞給LongOperation
構造函數,並使用它在onPostExecute
訪問TextView。
3)如何發送數據到onPostExecute
? 您必須在方法中返回它:
@Override
protected String doInBackground(String... urls) {
// do anything here.
return "String"; //Since return type is String. You can change that you anything and make sure it matches `onPostExecute` parameter type.
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.