2015-09-14 13 views
6

sto creando un'operazione CRUD in Android Studio ma continuavo a ricevere errori, l'errore è quando controllo il LogCat è quello che mi mostranoErrore di Android Studio: "Il metodo getText() deve essere chiamato dal thread UI, il thread attualmente dedotto è worker

line 156-158
1907-1931/com.example.casquejo.loginadmin E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #2 Process: com.example.casquejo.loginadmin, PID: 1907 java.lang.RuntimeException: An error occured while executing doInBackground() Caused by: java.lang.NullPointerException atcom.example.casquejo.loginadmin.NewProductActivity$CreateNewProduct.doInBackground(NewProductActivity.java:85) at com.example.casquejo.loginadmin.NewProductActivity$CreateNewProduct.doInBackground(NewProductActivity.java:58) atcom.example.casquejo.loginadmin.NewProductActivity$CreateNewProduct.onPreExecute(NewProductActivity.java:67) atcom.example.casquejo.loginadmin.NewProductActivity$1.onClick(NewProductActivity.java:53)

qualcuno può aiutarmi con questo o qualcuno può dare un'idea di come risolvere this` sotto è il codice per la mia classe Java EditProductActivity.class

 package com.example.casquejo.loginadmin; 

     import java.util.ArrayList; 
     import java.util.List; 
     import org.apache.http.NameValuePair; 
     import org.apache.http.message.BasicNameValuePair; 
     import org.json.JSONException; 
     import org.json.JSONObject; 
     import android.app.Activity; 
     import android.app.ProgressDialog; 
     import android.content.Intent; 
     import android.os.AsyncTask; 
     import android.os.Bundle; 
     import android.util.Log; 
     import android.view.View; 
     import android.widget.Button; 
     import android.widget.EditText; 

     /** 
     * Created by Casquejo on 9/14/2015. 
     */ 
     public class NewProductActivity extends Activity { 
    private ProgressDialog pDialog; 

    JSONParser jsonParser = new JSONParser(); 
    EditText inputName; 
    EditText inputPrice; 
    EditText inputDesc; 

    private static String url_create_product = "http://10.0.2.2/android_connect/create_product.php"; 

    private static final String TAG_SUCCESS = "success"; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.add_product); 

     inputName = (EditText) findViewById(R.id.inputName); 
     inputPrice = (EditText) findViewById(R.id.inputPrice); 
     inputDesc = (EditText) findViewById(R.id.inputDesc); 

     Button btnCreateProduct = (Button) findViewById(R.id.btnCreateProduct); 
     btnCreateProduct.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View view) { 
       String name = inputName.getText().toString(); 
       String price = inputPrice.getText().toString(); 
       String description = inputDesc.getText().toString(); 
       new CreateNewProduct().execute(name, price,description); 
      } 
     }); 
    } 

    class CreateNewProduct extends AsyncTask<String, String, String> { 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      pDialog = new ProgressDialog(NewProductActivity.this); 
      pDialog.setMessage("Creating Product.."); 
      pDialog.setIndeterminate(false); 
      pDialog.setCancelable(true); 
      pDialog.show(); 

     } 

     protected String doInBackground(String... args) { 

      String name = args[0], 
        price = args[1], 
        description = args[2]; 

      List<NameValuePair> params = new ArrayList<NameValuePair>(); 
      params.add(new BasicNameValuePair("name", name)); 
      params.add(new BasicNameValuePair("price", price)); 
      params.add(new BasicNameValuePair("description", description)); 

      JSONObject json = jsonParser.makeHttpRequest(url_create_product, 
        "POST", params); 

      Log.d("Create Response", json.toString()); 

      try { 
       int success = json.getInt(TAG_SUCCESS); 

       if (success == 1) { 
        Intent i = new Intent(getApplicationContext(), AllProductsActivity.class); 
        startActivity(i); 
        finish(); 
       } 
       else { 

       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 

      return null; 
     } 

     protected void onPostExecute(String file_url) { 
      pDialog.dismiss(); 
     } 

    } 
} 
+0

sarei molto attenti con questo codice, si sta chiamando 'findViewById (...)' per ottenere il riferimento ad elementi dell'interfaccia utente da un thread in background che esegue un runnable sul thread dell'interfaccia utente in un AsyncTask (che di per sé non ha senso!) e non stai utilizzando in modo difensivo alcuno dei widget dell'interfaccia utente che ti mette a rischio di eccezioni del puntatore nullo. Ad esempio, sposterei 'txtName = (EditText) findViewById (R.id.inputName);' e co il metodo 'onCreate()' – o0rebelious0o

risposta

6

l'IDE si riferisce alla

String name = txtName.getText().toString(); 
    String price = txtPrice.getText().toString(); 
    String description = txtDesc.getText().toString(); 

leggere i valori non dovrebbe essere un problema, ma al fine di sbarazzarsi di questo avviso/errore, è possibile spostarlo nel onClick e passare i valori tramite execute(). Per esempio.

btnSave.setOnClickListener(new View.OnClickListener() { 

    @Override 
    public void onClick(View arg0) { 
     String name = txtName.getText().toString(); 
     String price = txtPrice.getText().toString(); 
     String description = txtDesc.getText().toString(); 
     new SaveProductDetails().execute(name, price, description); 
    } 
}); 

quando doInBackground viene invocato, è possibile leggere quelli bac, attraverso le ex params, String... args. Il costrutto di tre punti rimane per vararg, e varargs può essere accesso come un array, usando la notazione []. Nel caso dell'esempio,

args[0] contiene il valore di name, args[1] contiene il valore di price e args[2] contiene il valore di description.

+0

Grazie mille! grazie per l'aiuto che tutti voi ho capito ora non posso davvero usarlo in DoInBackground grazie. – DayllCasquejo

+0

hai ancora problemi con questo? – Blackbelt

+0

signore ho fatto quello che hai suggerito nella tua risposta ma sto ancora avendo problemi quando controllo il logcat l'errore è il onClick e anche lo String ... args puoi aiutarmi con esso? – DayllCasquejo

5

è chiamiamo getText() da un thread in background generato da AsyncTask.

Prima recuperare il testo e quindi chiamare l'attività asincrona. Ecco un esempio

new SaveProductDetails() 
    .execute(txtName.getText().toString(), 
     txtPrice.getText().toString(), 
     txtDesc.getText().toString()); 

E dentro di SaveProductDetailsdoInBackground metodo:

String name = args[0], 
     price = args[1], 
     description = args[2]; 
+0

Grazie mille! grazie per l'aiuto che tutti voi ho capito ora non posso davvero usarlo in DoInBackground grazie. – DayllCasquejo

2

In un asynctask, il metodo doInBackground(...) viene eseguito in un thread in background (non-UI). Come puoi vedere nell'errore indicato, non ti è permesso interagire con gli elementi dell'interfaccia utente da un thread in background.

È possibile, passare gli argomenti nel thread in background come suggerito in una delle altre risposte oppure, è possibile modificare il tuo asynctask in modo tale che i valori della stringa UI vengano letti nel metodo onPreExecute() che viene eseguito sul thread dell'interfaccia utente (come il metodo onPostExecute()).

class SaveProductDetails extends AsyncTask<String, String, String> { 

private String name, price, description; 

@Override 
protected void onPreExecute() { 
    super.onPreExecute(); 
    pDialog = new ProgressDialog(EditProductActivity.this); 
    pDialog.setMessage("Saving product ..."); 
    pDialog.setIndeterminate(false); 
    pDialog.setCancelable(true); 
    pDialog.show(); 

    name = txtName.getText().toString(); 
    price = txtPrice.getText().toString(); 
    description = txtDesc.getText().toString(); 
} 

protected String doInBackground(String... args) { 
    //... Use as you would before 

Io suggerirei di dare un'occhiata a un blogpost come this di comprendere di più su AsyncTasks, come funzionano, come usarli compresi i dettagli come ad esempio quale metodo funziona su quale thread.

+0

Grazie mille! grazie per l'aiuto che tutti voi ho capito ora non posso davvero usarlo in DoInBackground grazie. – DayllCasquejo

+0

Se una delle risposte ti ha aiutato, non dimenticare di passare con le frecce a sinistra della risposta e contrassegnane una come accettata e correggi per aiutare gli altri a trovare la domanda in futuro :) – o0rebelious0o

+0

dang! haha tutte le risposte mi hanno aiutato, voglio sviare tutti e accettarlo. ma per i futuri lettori tutte le risposte sono corrette questi ragazzi mi hanno davvero aiutato molto :) – DayllCasquejo

0

È possibile leggere questo Using Variables on UI Thread from Worker Thread.
Nella tua domanda, stai provando ad accedere al testo di TextView dal thread in background. In ordine per essere coerenti come non dovresti farlo perché potrebbe essere possibile che il thread principale (filetto dell'interfaccia utente che imposta TextView allo stesso tempo).Per evitare tali scenari è possibile a qualcosa di simile:

class SaveProductDetails extends AsyncTask<String, String, String>{ 
     //create constructor and pass values of text view in it 
     String textViewValue1; 
     public SaveProductDetails (String textViewValue1){ 
      this.textViewValue1=textViewValue1 
     } 

    //other code below 
} 
0

Non è necessario passare il valore nel metodo execute. Imposta le variabili nome, prezzo e descrizione come globali. Per ottenere il valore da EditTest su un pulsante, fare clic sul codice come riportato di seguito:

Ogni volta che è necessario fare clic sul pulsante per ottenere i dati JSON.

btnSave.setOnClickListener(new View.OnClickListener() { 

    @Override 
    public void onClick(View arg0) { 
     name = txtName.getText().toString(); 
     price = txtPrice.getText().toString(); 
     description = txtDesc.getText().toString(); 
     new CreateNewProduct().execute(); 
    } 
}); 

Ora il nome, il prezzo e la descrizione hanno il suo valore indipendentemente dall'inserimento.

Ora la classe CreateNewProduct sembra che questo:

class CreateNewProduct extends AsyncTask<String, String, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     pDialog = new ProgressDialog(NewProductActivity.this); 
     pDialog.setMessage("Creating Product.."); 
     pDialog.setIndeterminate(false); 
     pDialog.setCancelable(true); 
     pDialog.show(); 

    } 

    protected String doInBackground(String... args) { 

     List<NameValuePair> params = new ArrayList<NameValuePair>(); 
     params.add(new BasicNameValuePair("name", name)); 
     params.add(new BasicNameValuePair("price", price)); 
     params.add(new BasicNameValuePair("description", description)); 

     JSONObject json = jsonParser.makeHttpRequest(url_create_product, 
       "POST", params); 

     Log.d("Create Response", json.toString()); 

     try { 
      int success = json.getInt(TAG_SUCCESS); 

      if (success == 1) { 
       Intent i = new Intent(getApplicationContext(), AllProductsActivity.class); 
       startActivity(i); 
       finish(); 
      } 
      else { 

      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    protected void onPostExecute(String file_url) { 
     pDialog.dismiss(); 
    } 

}

Problemi correlati