2011-12-08 18 views
7

Interessa la memoria se ho due classi Java che hanno chiamate native al codice C compilato e chiamo entrambe quelle classi in un'altra classe? Ad esempio, ho Classe A e Classe B con entrambe le chiamate alle funzioni native. Sono configurazione come questa:Chiamata JNI Java per caricare la libreria

public class A{ 
    // declare the native code function - must match ndkfoo.c 
    static { 
     System.loadLibrary("ndkfoo"); 
    } 

    private static native double mathMethod(); 

    public A() {} 

    public double getMath() { 
      double dResult = 0; 
      dResult = mathMethod(); 
      return dResult; 
    } 
} 


public class B{ 
    // declare the native code function - must match ndkfoo.c 
    static { 
     System.loadLibrary("ndkfoo"); 
    } 

    private static native double nonMathMethod(); 

    public B() {} 

    public double getNonMath() { 
      double dResult = 0; 
      dResult = nonMathMethod(); 
      return dResult; 
    } 
} 

Classe C quindi chiama entrambi, poiché entrambi fanno una chiamata statica per caricare la libreria si che la materia in classe C? O è meglio avere Classe C chiamata System.loadLibrary (...?

public class C{ 
    // declare the native code function - must match ndkfoo.c 
    // So is it beter to declare loadLibrary here than in each individual class? 
    //static { 
    // System.loadLibrary("ndkfoo"); 
    //} 
    // 

    public C() {} 

    public static void main(String[] args) { 
     A a = new A(); 
     B b = new B(); 
     double result = a.getMath() + b.getNonMath(); 

    } 
} 

risposta

7

No, non importa. È innocuo chiamare loadLibrary() più di una volta nello stesso classloader.

Dalla documentazione per Runtime.loadLibrary(String), che è chiamato da System.loadLibrary (String):

If this method is called more than once with the same library name, 
    the second and subsequent calls are ignored. 
1

è meglio avere la classe che usa la libreria, caricare la libreria. Se si deve caricare la libreria chiamante si rendono possibile chiamare i metodi nativi senza caricare la libreria.

0

Sembra come e NdkFoo classe sarebbe prudente, e hanno ogni metodo essere un nativo. Poi da a si potrebbe usare

NdkFoo.getInstance().mathMethod(); 

e B potrebbe fare

NdkFoo.getInstance().nonMathMethod(); 

Fa inoltre creare il nome della libreria nativa coerente con il nome della classe java di supporto.

1

Le librerie Jni sono librerie dinamiche. Penserei che dovrebbero essere per essere caricati da loadLibrary. Uno dei vantaggi delle librerie dinamiche è che se sono già caricati in memoria, quella copia viene utilizzata anziché essere ricaricata. Quindi è possibile utilizzare le due chiamate loadlibrary.

L'altro problema è che se si inserisce la chiamata loadlibrary in classe C, si è rovinato l'incapsulamento delle altre due classi. In qualsiasi progetto di grandi dimensioni, qualcuno alla fine chiamerà una delle chiamate native in classe a o in classe b senza passare per la classe c. Non funzionerà così bene.