我想要实现的目标如下: 在我看来,我有 4 个 TextView,它们应该显示所连接数据库中的项目数量。这是使用简单的 php 脚本完成的。
我遇到的问题是我从数据库中获取了所有正确的值,但是当我尝试将这些值设置到我的 TextView 时,应用程序崩溃了。
我试图看看使用许多 Asynctasks 是否会出现问题,但是当我决定注释掉 SetTextForTextView() 函数中的唯一一行时,这一切都像魅力一样工作预期值被打印到我的日志中。话虽这么说,我不认为同时使用多个异步任务是这里的问题,但我真的不知道是什么。
可能值得一提的是,当我像这样注释掉以下内容时,应用程序不会崩溃...
shoesAmount = (TextView) findViewById(R.id.menuTvShoesAmount);
DatabaseTask taskA = new DatabaseTask(shoesAmount);
taskA.execute("getAmount", "shoes");
// tshirtsAmounts = (TextView) findViewById(R.id.menuTvTshirtsAmount);
// DatabaseTask taskB = new DatabaseTask(tshirtsAmounts);
// taskB.execute("getAmount", "tshirts");
//
// jeansAmount = (TextView) findViewById(R.id.menuTvJeansAmount);
// DatabaseTask taskC = new DatabaseTask(jeansAmount);
// taskC.execute("getAmount", "jeans");
//
// blousesAmount = (TextView) findViewById(R.id.menuTvBlousesAmount);
// DatabaseTask taskD = new DatabaseTask(blousesAmount);
// taskD.execute("getAmount", "blouses");
但是,如果再使用任何其他组合(例如像这样的组合),应用程序就会再次崩溃......
// shoesAmount = (TextView) findViewById(R.id.menuTvShoesAmount);
// DatabaseTask taskA = new DatabaseTask(shoesAmount);
// taskA.execute("getAmount", "shoes");
//
tshirtsAmounts = (TextView) findViewById(R.id.menuTvTshirtsAmount);
DatabaseTask taskB = new DatabaseTask(tshirtsAmounts);
taskB.execute("getAmount", "tshirts");
//
// jeansAmount = (TextView) findViewById(R.id.menuTvJeansAmount);
// DatabaseTask taskC = new DatabaseTask(jeansAmount);
// taskC.execute("getAmount", "jeans");
//
// blousesAmount = (TextView) findViewById(R.id.menuTvBlousesAmount);
// DatabaseTask taskD = new DatabaseTask(blousesAmount);
// taskD.execute("getAmount", "blouses");
有人可以指出我可能出错的方向吗?
谢谢! (这是完整的代码)
package ishopper.theindiestudio.com.appname;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
public class Menu extends AppCompatActivity {
private ImageButton btnHelp, btnAccount, newest1, newest2, newest3;
private TextView shoesAmount, tshirtsAmounts, jeansAmount, blousesAmount;
private Button browseShoes, browseTshirts, browseJeans, browseBlouses;
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
context = this;
btnHelp = (ImageButton) findViewById(R.id.menuBtnHelp);
btnAccount = (ImageButton) findViewById(R.id.menuBtnAccount);
btnAccount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onAccountOptions();
}
});
btnHelp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onHelp();
}
});
newest1 = (ImageButton) findViewById(R.id.menuIbNewest1);
newest2 = (ImageButton) findViewById(R.id.menuIbNewest2);
newest3 = (ImageButton) findViewById(R.id.menuIbNewest3);
//set newest items
shoesAmount = (TextView) findViewById(R.id.menuTvShoesAmount);
DatabaseTask taskA = new DatabaseTask(shoesAmount);
taskA.execute("getAmount", "shoes");
tshirtsAmounts = (TextView) findViewById(R.id.menuTvTshirtsAmount);
DatabaseTask taskB = new DatabaseTask(tshirtsAmounts);
taskB.execute("getAmount", "tshirts");
jeansAmount = (TextView) findViewById(R.id.menuTvJeansAmount);
DatabaseTask taskC = new DatabaseTask(jeansAmount);
taskC.execute("getAmount", "jeans");
blousesAmount = (TextView) findViewById(R.id.menuTvBlousesAmount);
DatabaseTask taskD = new DatabaseTask(blousesAmount);
taskD.execute("getAmount", "blouses");
}
public void SetTextForTextView(TextView textview, String result){
textview.setText(result);
}
public void onAccountOptions () {
Intent i = new Intent(this, AccountDetailsActivity.class);
startActivity(i);
}
public void onHelp () {
}
public void onBackPressed() {
//disabled back button
}
private class DatabaseTask extends AsyncTask<String, Void, String> {
private String taskType;
private String productType;
private TextView textView;
private ImageButton imageButton;
DatabaseTask (TextView mTextView){textView = mTextView;}
@Override
protected String doInBackground(String... params) {
String task = params[0];
if (task.equals("getAmount")) {
Log.e("doInBg", "getAmount");
String login_url = "http://url.eu/directory/script.php";
String tProductType = params[1];
try {
URL url = new URL(login_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String postData = URLEncoder.encode("producttable", "UTF-8") + "=" + URLEncoder.encode(tProductType, "UTF-8");
bufferedWriter.write(postData);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
Log.e("doInBgResult", result.toString());
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
Menu activity = (Menu) context;
activity.SetTextForTextView(textView, result.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
}
最佳答案
AsyncTask
的 doInBackground()
在另一个线程中运行,您无法从另一个线程更改 UI,只能从主线程更改 UI。我建议您在完成长期工作后在 onPostExecute()
中执行相同的工作。将要使用的字符串结果
返回到主线程
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
// no need for that
//Menu activity = (Menu) context;
//activity.SetTextForTextView(textView, result.toString());
reutrn result;
然后更新文本
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result != null){
SetTextForTextView(textView, result);
}
}
关于java - 使用 Asynctasks 将文本设置为多个 TextField 会导致应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36830262/