web-dev-qa-db-fra.com

Comment appeler getResources () depuis une classe qui n'a pas de contexte?

Dans mon application, j'ai beaucoup de cours et d'activités. Droid est une classe qui n'a pas de contexte. Mygame est une classe qui étend SurfaceView et implémente SurfaceHolder.Callback . Je crée un objet de Droid dans la classe mygame et en définit l’image et la position. Le code que j'ai écrit pour cela est donné ci-dessous.

block1 = new Droid(BitmapFactory.decodeResource(getResources(), R.drawable.birdpic), 100, 10);

Le constructeur de la classe Droid est donné ci-dessous.

public Droid(Bitmap bitmap, int x, int y) {

    this.bitmap = bitmap;
    this.x = x;
    this.y = y;
}   

Dans un scénario particulier, je dois définir l'image d'arrière-plan et la position de l'objet Droid à partir de la classe Droid elle-même.Voici, je suis confronté au problème.

if(checkflag)
{
    myObj.centerblock=new Droid(BitmapFactory.decodeResource(getResources(), R.drawable.blast), myObj.xpos, myObj.ypos);
}   

Le problème est que la classe Droid n'a pas de contexte. Donc, je ne peux pas utiliser getResources () ici. J'ai essayé le code ci-dessous mais il se bloque.

if(checkflag)
{
    myObj.centerblock=new Droid(BitmapFactory.decodeResource(myObj.getResources(), R.drawable.blast), myObj.xpos, myObj.ypos);
}

Quelqu'un peut-il m'aider? Je veux juste définir l'image d'arrière-plan et la positionner pour l'objet Droid à partir de la classe Droid elle-même. 

57
andro-girl

Un contexte est un descripteur du système. il fournit des services tels que la résolution de ressources, l'accès aux bases de données et aux préférences, etc. C'est une "interface" qui permet d'accéder aux ressources spécifiques à l'application, à la classe et aux informations relatives à l'environnement de l'application. Vos activités et services étendent également le contexte pour hériter de toutes ces méthodes pour accéder aux informations d'environnement dans lesquelles l'application est en cours d'exécution.

Cela signifie que vous devez obligatoirement passer le contexte à la classe spécifique si vous voulez obtenir/modifier des informations spécifiques sur les ressources . Vous pouvez passer le contexte dans le constructeur comme

public classname(Context context, String s1) 
{
...
}
52
Ali

La solution normale consiste à transmettre une instance du contexte à la classe lors de sa création, ou après sa création, mais avant, vous devez utiliser le contexte.

Une autre solution consiste à créer un objet Application avec une méthode statique pour accéder au contexte de l'application bien que cela couple l'objet Droid de manière assez étroite dans le code.

Modifier, exemples ajoutés

Soit modifier la classe Droid pour qu'elle ressemble à ceci

 public Droid(Context context,int x, int y) {
    this.bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.birdpic);
    this.x = x;
    this.y = y;
    }   

Ou créez une application comme ceci:

public class App extends Android.app.Application
{
    private static App mApp = null;
    /* (non-Javadoc)
     * @see Android.app.Application#onCreate()
     */
    @Override
    public void onCreate()
    {
        super.onCreate();
        mApp = this;
    }
    public static Context context()
    {
        return mApp.getApplicationContext();
    }
}

Et appelez App.context () chaque fois que vous avez besoin d'un contexte - notez cependant que toutes les fonctions ne sont pas disponibles dans un contexte d'application, certaines ne sont disponibles que dans un contexte d'activité, mais vous aurez certainement besoin de getResources ().

Notez que vous devrez ajouter Android: name à la définition de votre application dans votre manifeste, à peu près comme ceci:

<application
    Android:icon="@drawable/icon"
    Android:label="@string/app_name"
    Android:name=".App" >
28
zeetoobiker

Exemple: Obtention de la chaîne app_name:

Resources.getSystem().getString( R.string.app_name )
25
clive

Ça fonctionne toujours pour moi:

import Android.app.Activity;
import Android.content.Context;

public class yourClass {

 Context ctx;

 public yourClass (Handler handler, Context context) {
 super(handler);
    ctx = context;
 }

 //Use context (ctx) in your code like this:
 block1 = new Droid(BitmapFactory.decodeResource(ctx.getResources(), R.drawable.birdpic), 100, 10);
 //OR
 builder.setLargeIcon(BitmapFactory.decodeResource(ctx.getResources(), R.drawable.birdpic));
 //OR
 final Intent intent = new Intent(ctx, MainActivity.class);
 //OR
 NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
 //ETC...

}

Pas lié à cette question mais exemple utilisant un fragment pour accéder aux ressources/activités du système comme ceci:

public boolean onQueryTextChange(String newText) {
 Activity activity = getActivity();
 Context context = activity.getApplicationContext();
 returnSomething(newText);
 return false;
}

View customerInfo = getActivity().getLayoutInflater().inflate(R.layout.main_layout_items, itemsLayout, false);
 itemsLayout.addView(customerInfo);
1
Elroy

Cela peut facilement être fait si vous aviez déclaré une classe qui s'étend de Application

Cette classe ressemblera à un singleton, donc quand vous avez besoin d’un contexte, vous pouvez l’obtenir comme ceci:

Je pense que c'est la meilleure réponse et le nettoyeur

Voici mon code du paquet Utilities:

 public static String getAppNAme(){
     return MyOwnApplication.getInstance().getString(R.string.app_name);
 }
0
Catluc