我尝试使用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中显示服务器内的消息。
像androholic所说:
您不应该从代码中手动调用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”,因为我只是用它来读取服务器内的数据,而不是在任何地方检索它。
答案 0 :(得分:2)
您不应该从代码中手动调用onPostExecute
。在asynctask上调用execute
就足够了。当asynctask完成其工作时,将自动调用onPostExecute
。
答案 1 :(得分:1)
您的doInBackground()
方法仅返回null。如初。
您的onPostExecute()
方法未被调用,因为它没有覆盖AsyncTask
的{{1}}方法,这会占用onPostExecute()
个参数
答案 2 :(得分:1)
首先关于您的活动中的问题:
LongOperation longOperation = new LongOperation(MainActivity.this);
longOperation.execute(serverURL);
longOperation.onPostExecute(uiUpdate);
longOperation.execute(serverURL);
是一种异步方法。这意味着您的程序将在执行方法后立即调用longOperation.onPostExecute(uiUpdate);
,而无需等待doInBackground
中的结果。
你做不到,你不应该这样做。 onPostExecute
返回结果后立即自动调用doInBackground
(您现在返回null
。)
LongOperation longOperation = new LongOperation(MainActivity.this); longOperation.execute(serverURL使用); longOperation.onPostExecute(uiUpdate);
现在的解决方案:
1)doInBackground
返回类型应始终等于onPostExecute
参数。
如果您返回String,那么onPostExecute
将如下所示:
protected void onPostExecute(String string) {
}
2)如何设置TextView
中的Activity
。最简单的方法是将活动变量传递给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.
}