对Android新手可以任何人建议我,哪里做错了? 整个ManiActiviy.java
错误是'必须从UI线程调用方法getText,当前推断的线程是worker'
在这3行中,它给出了上述错误。
person = new Person();
person.setName(etName.getText().toString());
person.setCountry(etCountry.getText().toString());
person.setTwitter(etTwitter.getText().toString());
班级代码
import android.app.Activity;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.appindexing.Thing;
import com.google.android.gms.common.api.GoogleApiClient;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class MainActivity extends Activity implements OnClickListener {
TextView tvIsConnected;
EditText etName, etCountry, etTwitter;
Button btnPost;
Person person;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get reference to the views
tvIsConnected = (TextView) findViewById(R.id.tvIsConnected);
etName = (EditText) findViewById(R.id.etName);
etCountry = (EditText) findViewById(R.id.etCountry);
etTwitter = (EditText) findViewById(R.id.etTwitter);
btnPost = (Button) findViewById(R.id.btnPost);
// check if you are connected or not
if (isConnected()) {
tvIsConnected.setBackgroundColor(0xFF00CC00);
tvIsConnected.setText("You are conncted");
} else {
tvIsConnected.setText("You are NOT conncted");
}
// add click listener to Button "POST"
btnPost.setOnClickListener(this);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
public static String POST(String url, Person person) {
InputStream inputStream = null;
String result = "";
try {
// 1. create HttpClient
HttpClient httpclient = new DefaultHttpClient();
// 2. make POST request to the given URL
HttpPost httpPost = new HttpPost(url);
String json = "";
// 3. build jsonObject
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("name", person.getName());
jsonObject.accumulate("country", person.getCountry());
jsonObject.accumulate("twitter", person.getTwitter());
// 4. convert JSONObject to JSON to String
json = jsonObject.toString();
// ** Alternative way to convert Person object to JSON string usin Jackson Lib
// ObjectMapper mapper = new ObjectMapper();
// json = mapper.writeValueAsString(person);
// 5. set json to StringEntity
StringEntity se = new StringEntity(json);
// 6. set httpPost Entity
httpPost.setEntity(se);
// 7. Set some headers to inform server about the type of the content
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
// 8. Execute POST request to the given URL
HttpResponse httpResponse = httpclient.execute(httpPost);
// 9. receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
// 10. convert inputstream to string
if (inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
// 11. return result
return result;
}
public boolean isConnected() {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Activity.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected())
return true;
else
return false;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnPost:
if (!validate())
Toast.makeText(getBaseContext(), "Enter some data!", Toast.LENGTH_LONG).show();
// call AsynTask to perform network operation on separate thread
new HttpAsyncTask().execute("http://hmkcode.appspot.com/jsonservlet");
break;
}
}
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
public Action getIndexApiAction() {
Thing object = new Thing.Builder()
.setName("Main Page") // TODO: Define a title for the content shown.
// TODO: Make sure this auto-generated URL is correct.
.setUrl(Uri.parse("http:// http://192.168.0.51:1337/sensormessage/pushSensorData?MAC=18:fe:34:a5:df:8c&OC=0&ALS=3 &POW=100"))
.build();
return new Action.Builder(Action.TYPE_VIEW)
.setObject(object)
.setActionStatus(Action.STATUS_TYPE_COMPLETED)
.build();
}
@Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
AppIndex.AppIndexApi.start(client, getIndexApiAction());
}
@Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
AppIndex.AppIndexApi.end(client, getIndexApiAction());
client.disconnect();
}
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
person = new Person();
person.setName(etName.getText().toString());
person.setCountry(etCountry.getText().toString());
person.setTwitter(etTwitter.getText().toString());
return POST(urls[0], person);
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
Toast.makeText(getBaseContext(), "Data Sent!", Toast.LENGTH_LONG).show();
}
}
private boolean validate() {
if (etName.getText().toString().trim().equals(""))
return false;
else if (etCountry.getText().toString().trim().equals(""))
return false;
else if (etTwitter.getText().toString().trim().equals(""))
return false;
else
return true;
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
String result = "";
while ((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
}
And Person.java
package android.hmkcode.com.android_post_json;
/**
* Created by HP on 2/2/2017.
*/
public class Person {
private String name;
private String country;
private String twitter;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getTwitter() {
return twitter;
}
public void setTwitter(String twitter) {
this.twitter = twitter;
}
}
答案 0 :(得分:0)
尝试将EditText
变量与类HttpAsyncTask
构造函数一起传递为:
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
EditText etName;
EditText etCountry;
EditText etTwitter;
Context context;
//Constructor to get the values
public HttpAsyncTask(EditText etName, EditText etCountry, EditText etTwitter, Context context){
this.etName = etName;
this.etCountry = etCountry;
this.etTwitter = etTwitter;
this.context = context;
}
@Override
protected String doInBackground(String... urls) {
person = new Person();
person.setName(etName.getText().toString());
person.setCountry(etCountry.getText().toString());
person.setTwitter(etTwitter.getText().toString());
return POST(urls[0], person);
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
Toast.makeText(context, "Data Sent!", Toast.LENGTH_LONG).show();
}
}
并将editext变量传递给:
new HttpAsyncTask(etName, etCountry, etTwitter, MainActivity.this).execute("http://hmkcode.appspot.com/jsonservlet");
答案 1 :(得分:0)
您无法访问后台线程(工作线程)中的视图
您可以像这样修改您的代码
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
person = new Person();
person.setName(urls[1]); //name
person.setCountry(urls[2]); //country
person.setTwitter(urls[3]); // twitter
return POST(urls[0], person);
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
Toast.makeText(getBaseContext(), "Data Sent!", Toast.LENGTH_LONG).show();
}
}
并像这样打电话
new HttpAsyncTask().execute("http://hmkcode.appspot.com/jsonservlet",etName.getText().toString(),etCountry.getText().toString(),etTwitter.getText().toString());
答案 2 :(得分:-1)
除非使用Looper,否则无法访问工作线程中的UI组件(因为doInBackground创建工作线程)。
解决方案1:
在 onPreExecute()方法中,您可以访问ui组件,因为它在UI线程本身中运行。请执行以下操作
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
Person person;
@Override
protected void onPreExecute(){
person = new Person();
person.setName(etName.getText().toString());
person.setCountry(etCountry.getText().toString());
person.setTwitter(etTwitter.getText().toString());
}
@Override
protected String doInBackground(String... urls) {
return POST(urls[0], person);
}
解决方案2 只需在onClick之后创建一个Person,并在AsynTask()
的构造函数中传递person对象 @Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnPost:
if (!validate())
Toast.makeText(getBaseContext(), "Enter some data!", Toast.LENGTH_LONG).show();
person = new Person();
person.setName(etName.getText().toString());
person.setCountry(etCountry.getText().toString());
person.setTwitter(etTwitter.getText().toString());
// call AsynTask to perform network operation on separate thread
new HttpAsyncTask(person).execute("http://hmkcode.appspot.com/jsonservlet");
break;
}
}
在构造函数中,您需要以下内容。
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
Person person;
Context context;
//Constructor to get the values
public HttpAsyncTask(Person person, Context context){
this.person= person;
this.context = context;
}
@Override
protected String doInBackground(String... urls) {
return POST(urls[0], person);
}