2017-02-03 78 views
0

剛剛接觸android的人可以任何一個建議我,在哪裏做錯了? 全ManiActiviy.javaAndroid錯誤方法getText必須從UI線程調用,當前推斷的線程是工作人員

錯誤是「方法的getText必須從UI線程調用,目前推測線程是工人」

在這些第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; 

    } 
} 

而且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

考慮接受一個答案,如果幫助任何! – W4R10CK

回答

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"); 
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()); 
-1

您無法訪問工作線程中的UI組件(如doInBackground創建工作區除非你使用Looper)。
解決方案1: Inside 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後的人,並通過人物對象的AsynTask的構造函數()

@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); 

    } 
+0

如果有人投票回答......至少在評論中提及原因 –

相關問題