2011-11-23 8 views
51

Nella mia domanda ho molte classi e attività. Droid è una classe che non ha contesto. Mygame è una classe che estende SurfaceView e implementa SurfaceHolder.Callback. Sto creando un oggetto di Droid nella classe mygame e impostando l'immagine di sfondo e la posizione per esso. Di seguito il codice che ho scritto per questo.Come chiamare getResources() da una classe che non ha contesto?

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

Il costruttore di classe Droid è indicato di seguito.

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

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

In uno scenario particolare devo impostare l'immagine di sfondo e la posizione dell'oggetto Droid dalla classe Droid itself.Here sto affrontando l'issue.Given sotto è il frammento di codice per fare questo.

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

Il problema è che la classe Droid non ha contesto. Quindi non posso usare getResources() qui. Ho provato il codice qui sotto ma si blocca.

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

Qualcuno può aiutarmi. Voglio solo impostare l'immagine di sfondo e posizionarla per l'oggetto Droid dalla classe Droid stessa.

+1

possibile duplicato del [Utilizzando getResources() in classe non-attività] (http://stackoverflow.com/ domande/7666589/using-getresources-in-non-activity-class) –

risposta

46

Un contesto è una maniglia per il sistema; fornisce servizi come la risoluzione delle risorse, l'accesso ai database e alle preferenze e così via. Si tratta di una "interfaccia" che consente l'accesso a risorse specifiche dell'applicazione e classe e informazioni sull'ambiente dell'applicazione. Anche le attività e i servizi estendono il contesto per ereditare tutti questi metodi per accedere alle informazioni sull'ambiente in cui è in esecuzione l'applicazione.

Ciò significa che è necessario passare il contesto alla classe specifica se si desidera ottenere/modificare alcune informazioni specifiche sulle risorse. È possibile passare contesto nel costruttore come

public classname(Context context, String s1) 
{ 
... 
} 
+0

è possibile impostare il contesto per la classe Droid ... non sta estendendo l'attività o altre classi –

+2

non è necessario estendere un'attività. È possibile passare il contesto a questa classe quando si inizializza questa classe da alcune attività. – Ali

28

La soluzione normale a questo è passare un'istanza del contesto alla classe mentre la si crea, o dopo che è stata creata prima, ma prima è necessario utilizzare il contesto.

Un'altra soluzione è creare un oggetto Application con un metodo statico per accedere al contesto dell'applicazione, sebbene questo accoppi il Droid piuttosto strettamente nel codice.

Modifica, esempi aggiunto

o modificare la classe di Droid di essere qualcosa di simile

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

o creare un qualcosa di domanda come questa:

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(); 
    } 
} 

e chiamare App. context() ovunque sia necessario un contesto - si noti tuttavia che non tutte le funzioni sono disponibili in un contesto applicativo, alcune sono solo disponibili imposta su un contesto di attività, ma lo farà sicuramente con il tuo bisogno di getResources().

Si prega di notare che è necessario aggiungere Android: un nome alla vostra definizione di applicazione nel vostro manifesto, qualcosa di simile:

<application 
    android:icon="@drawable/icon" 
    android:label="@string/app_name" 
    android:name=".App" > 
+0

Usind bitmap Android fornisce anche un accoppiamento stretto al codice Android. Io di solito provo a separare il codice relativo all'interfaccia e le applicazioni specifiche (non sono riuscito con successo) –

+0

@zeetoobiker ... puoi spiegare queste cose? Non ho capito ... non sono così familiare con Android. –

+0

Non intendevo veramente un accoppiamento stretto con il codice Android (supponendo che tu avessi accesso all'oggetto Application con un metodo statico), piuttosto che la classe Droid sarà strettamente accoppiata al progetto in cui si trova attualmente - non sarai in grado di usarlo in un progetto diverso senza riscrivere gli interni. Per essere onesti, una classe in un'app Android che si occupa di funzioni di visualizzazione sarà strettamente collegata ad Android, quindi non mi preoccuperei di ciò. – zeetoobiker

22

Esempio: Ottenere nome_app stringa:

Resources.getSystem().getString(R.string.app_name) 
+15

Utilizza solo le risorse di sistema, non le risorse App, che nel 99% dei casi non funzioneranno – Adam

+0

sì ... questo non ha funzionato neanche per me. Avevo bisogno di arrivare alle risorse dell'app per una traduzione enum su stringhe e quelle non trovate. Finito per dover creare una funzione che ha mappato l'enum a una risorsa e utilizzato l'attività come parlato altrove in questo post. –

1

Questo funziona sempre per me:

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... 

} 

Non relativa a questa domanda, ma esempio di utilizzo un frammento per accedere alle risorse di sistema/attività come questa:

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

Si può essere fatto facilmente se u aveva dichiarato una classe che si estende da Application

Questa classe sarà come un Singleton, così quando u bisogno di un contesto u può ottenere proprio come questo:

I pensare che questa è la risposta migliore e più pulito il

Ecco il mio codice da pacchetto di Utilità:

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