我正在尝试从HttpPost下载字符串,我正在使用Async类来执行此操作。但是,当我运行应用程序时,它会崩溃。这是我第一次使用Async类,我担心我有些傻,你能帮我找到错误吗?
请注意,我还想在获取字符串时更新我的列表视图。我尝试这样做,买一个单独的方法。
代码:
public static final String PREFS_NAME = "MyPrefsFile";
BufferedReader in = null;
String data = null;
String username;
List headlines;
List links;
String password;
ArrayAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// listview method
ContactsandIm();
new loadcontactsandIm().execute(PREFS_NAME);
}
public class loadcontactsandIm extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
/* login.php returns true if username and password is equal to saranga */
HttpPost httppost = new HttpPost("http://gta5news.com/login.php");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", username));
nameValuePairs.add(new BasicNameValuePair("password", password));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
Log.w("HttpPost", "Execute HTTP Post Request");
HttpResponse response = httpclient.execute(httppost);
Log.w("HttpPost", "Execute HTTP Post Request");
in = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent()));
StringBuffer sb = new StringBuffer("");
String l ="";
String nl ="";
while ((l =in.readLine()) !=null) {
sb.append(l + nl);
}
in.close();
data = sb.toString();
ListView lv = getListView();
lv.setTextFilterEnabled(true);
headlines.add(data);
setListAdapter(adapter);
return null;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
private StringBuilder inputStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// Read response until the end
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Return full string
return total;
}
}
public void ContactsandIm() {
headlines = new ArrayList();
//get prefs
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String username = settings.getString("key1", null);
String password = settings.getString("key2", null);
if(username.equals("irock97")) {
Toast toast=Toast.makeText(this, "Hello toast", 2000);
toast.setGravity(Gravity.TOP, -30, 50);
toast.show();
} else {
Toast toast=Toast.makeText(this, "Hello toast", 2000);
toast.setGravity(Gravity.TOP, -30, 150);
toast.show();
}
ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, headlines);
}
}
logcat的:
03-25 13:47:37.356: E/AndroidRuntime(2484): FATAL EXCEPTION: AsyncTask #1
03-25 13:47:37.356: E/AndroidRuntime(2484): java.lang.RuntimeException: An error occured while executing doInBackground()
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.os.AsyncTask$3.done(AsyncTask.java:200)
03-25 13:47:37.356: E/AndroidRuntime(2484): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
03-25 13:47:37.356: E/AndroidRuntime(2484): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
03-25 13:47:37.356: E/AndroidRuntime(2484): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
03-25 13:47:37.356: E/AndroidRuntime(2484): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
03-25 13:47:37.356: E/AndroidRuntime(2484): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
03-25 13:47:37.356: E/AndroidRuntime(2484): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
03-25 13:47:37.356: E/AndroidRuntime(2484): at java.lang.Thread.run(Thread.java:1096)
03-25 13:47:37.356: E/AndroidRuntime(2484): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.view.ViewRoot.requestLayout(ViewRoot.java:594)
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.view.View.requestLayout(View.java:8125)
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.view.View.requestLayout(View.java:8125)
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.view.View.requestLayout(View.java:8125)
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.view.ViewGroup.removeAllViews(ViewGroup.java:2255)
03-25 13:47:37.356: E/AndroidRuntime(2484): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:196)
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.app.Activity.setContentView(Activity.java:1647)
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.app.ListActivity.ensureList(ListActivity.java:314)
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.app.ListActivity.getListView(ListActivity.java:299)
03-25 13:47:37.356: E/AndroidRuntime(2484): at com.gta5news.bananaphone.ChatService$loadcontactsandIm.doInBackground(ChatService.java:87)
03-25 13:47:37.356: E/AndroidRuntime(2484): at com.gta5news.bananaphone.ChatService$loadcontactsandIm.doInBackground(ChatService.java:1)
03-25 13:47:37.356: E/AndroidRuntime(2484): at android.os.AsyncTask$2.call(AsyncTask.java:185)
03-25 13:47:37.356: E/AndroidRuntime(2484): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
答案 0 :(得分:2)
您在doInBackground中设置ListView适配器。永远不要在UI线程之外操纵UI
答案 1 :(得分:2)
您无法与主线程之外的任何其他线程中的UI元素进行交互。您需要在onPostExecute
方法中执行ListView的所有交互。
基本上,您需要在doInBackground方法中编译Web请求中的所有数据,存储在您的任务实例上,然后在onPostExecute上获取列表视图并设置适配器并填充数据。
答案 2 :(得分:2)
你在doInBackground工作,并在onPostExecute上使用你的工作结果。
示例:
public class TestActivity extends Activity
{
private GetTask getTask;
public ListView fList;
@Override
public void onCreate(Bundle savedInstanceState)
{
getTask = new GetTask();
getTask.execute();
fList = (ListView) findViewById(R.id.lstview);
}
public class GetTask extends AsyncTask<Void, Void, List>
{
@Override
protected List doInBackground(Void... params) {
return load();
}
@Override
protected void onPostExecute(List result) {
ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, headlines);
fList.setAdapter(adapter);
}
}
private List load() {
// get your data from http
// add to your list, probably you can use model.
List headlines;
headlines.add(data);
return headlines;
}
}
答案 3 :(得分:1)
首先,您不能在doInBackground()中处理与UI相关的任务中的任何UI相关任务,我们有一个方法调用onPostExecute(),我们可以处理所有与ui相关的任务。 如果您仍然不想使用这些方法并在doInBackground()中处理它,那么您可以在下面的代码中执行::::
runOnUiThread(new Runnable() {
public void run() {
//your UI related code stuff
ListView lv = getListView();
lv.setTextFilterEnabled(true);
headlines.add(data);
setListAdapter(adapter); //do what you like here
}
});