2012-08-31 2 views
6

Il m'a fallu beaucoup de temps pour que cela fonctionne, mais ce n'est clairement pas la meilleure pratique. En bref, j'ai besoin d'afficher une boîte de dialogue lorsque ma tâche asynchrone se termine, mais getApplicationContext() ne fonctionne pas, pas plus que de le passer en paramètre lors de la création de la tâche asynchrone. J'ai donc déclaré une variable publique pour le contexte dans ma classe AsyncTask et mis en avant Execute:Android AsyncTask Meilleure façon d'accéder au contexte de l'activité

private OnClickListener clickLoadRefs = new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     Log.d("H","Clicked Load Refs"); 
     RefreshRefPoints refreshRefPoints = new RefreshRefPoints(); 
     refreshRefPoints.myCtx=v.getContext(); 
     refreshRefPoints.execute(v.getContext()); 
    } 
}; 

private class RefreshRefPoints extends AsyncTask<Context, Integer, Integer> { 

    private Integer nPoints=0; 
    public Context myCtx; 
    private ProgressDialog pd; 

    protected Integer doInBackground(Context... ctx) { 
     Log.d("H","doInBackground()"); 
     dbHelper.clearRefPoints(); 
     requestRefPoints(); 
     nPoints = parseRefPointsCSV(); 

     return nPoints; 
    } 

    protected void onProgressUpdate(Integer... progress) { 
    } 

    protected void onPreExecute() 
    { 
     pd = ProgressDialog.show(myCtx, "Refreshing Reference Points", "Loading...", true,false); 
     Log.d("H", "onPreExecute()"); 
    } 
    protected void onPostExecute(Integer result) { 
     pd.dismiss(); 
     AlertDialog.Builder builder = new AlertDialog.Builder(myCtx); 
     builder.setTitle("Reference points refresh complete"); 
     builder.setMessage(result+" records loaded"); 
     builder.setPositiveButton("OK",null); 
     builder.show(); 
     Log.d("H","onPostExecute()");  
    }...etc 

Quelqu'un peut-il me montrer la bonne façon de passer le contexte?

Merci

Répondre

12

définir une méthode de constructeur et de passer un paramètre contextuel. Ce serait mieux.

Voici ce que je voulais dire:

private class RefreshRefPoints extends AsyncTask<Void, Integer, Integer> { 

    private Integer nPoints=0; 
    private Context myCtx; 
    private ProgressDialog pd; 

    public RefreshRefPoints(Context ctx){ 
     // Now set context 
     this.myCtx = ctx; 
    } 

} 

C'est tout.

+1

Mais il donne des fuites de mémoire –

2

contexte de passe dans le constructeur comme

private OnClickListener clickLoadRefs = new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     Log.d("H","Clicked Load Refs"); 
     RefreshRefPoints refreshRefPoints = new RefreshRefPoints(Your_ActivityName.this); 
     refreshRefPoints.myCtx=v.getContext(); 
     refreshRefPoints.execute(v.getContext()); 
    } 
}; 


private class RefreshRefPoints extends AsyncTask<Void, Integer, Integer> { 

    private Integer nPoints=0; 
    public Context myCtx; 
    private ProgressDialog pd; 

public RefreshRefPoints (Context ctx) { 
    myCtx = ctx; 
} 
+0

Merci de travailler, mais je reçois des plaintes d'eclipse re par doInBackground maintenant que j'ai changé la ligne "extends AsyncTask " selon votre échantillon? –

+1

put ** Void ** dans Integer protégé doInBackground (** Void ** ...) { –

+0

Dans le contexte moderne de tout faire avec des fragments, la valeur de cette réponse est dégradante. – ed209

10

Vous pouvez également utiliser YourActivityName.this pour faire référence à l'activité Context. Étant donné que les activités étendent le contexte, il est donc possible de le faire.

+0

Merci - ne se rendait pas compte! –

+1

Notez que si votre activité n'est pas instanciée ou supprimée, l'appel du code dans cette réponse entraînera une exception NullPointerException. –

Questions connexes