2011-12-08 33 views
7

Liệu nó có ảnh hưởng đến bộ nhớ nếu tôi có hai lớp Java có các cuộc gọi gốc tới mã C đã biên dịch và tôi gọi cả hai lớp đó trong một lớp khác không? Ví dụ tôi có Class A và Class B với cả hai cuộc gọi đến các hàm gốc. Chúng được thiết lập như sau:Java JNI gọi để tải thư viện

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

Lớp C sau đó gọi cả hai vì cả hai thực hiện cuộc gọi tĩnh để tải thư viện sẽ quan trọng trong lớp C? Hoặc là nó tốt hơn để có Class C gọi 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(); 

    } 
} 

Trả lời

7

Không, không quan trọng. Thật vô hại khi gọi hàm loadLibrary() nhiều lần trong cùng một trình nạp lớp.

Từ tài liệu cho Runtime.loadLibrary(String), được gọi là bởi System.loadLibrary (String):

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

của nó tốt hơn để có lớp trong đó sử dụng thư viện, load thư viện. Nếu bạn có đến người gọi nạp thư viện bạn thực hiện nó có thể gọi các phương pháp tự nhiên mà không cần nạp thư viện.

0

có vẻ như và NdkFoo lớp sẽ được thận trọng, và có mọi phương pháp có một nguồn gốc. Sau đó, từ A bạn có thể sử dụng

NdkFoo.getInstance().mathMethod(); 

và B có thể làm

NdkFoo.getInstance().nonMathMethod(); 

Nó cũng làm cho việc tạo tên thư viện gốc phù hợp với tên lớp java sao lưu.

1

Ức chế Jni là libs động. Tôi nghĩ rằng họ sẽ phải được để được nạp bởi loadLibrary. Một trong những ưu điểm của thư viện động là nếu chúng đã được nạp vào bộ nhớ, bản sao đó sẽ được sử dụng thay vì được nạp lại. Vì vậy, bạn có thể sử dụng hai cuộc gọi thư viện tải.

Vấn đề khác là nếu bạn đặt lệnh gọi bộ nạp trong lớp C, bạn đã hủy hoại việc đóng gói của hai lớp kia. Trong bất kỳ dự án lớn nào, một người nào đó cuối cùng sẽ gọi một trong các cuộc gọi bản địa trong lớp a hoặc lớp b mà không qua lớp c. Điều đó sẽ không hoạt động tốt.