2013-05-13 35 views
8

Tôi viết một trò chơi, và tôi có thư viện bản địa rất lớn, tôi đang cố gắng để tải thư viện mẹ đẻ của tôi vào các hoạt động chính của tôi nhưdo: java.lang.UnsatisfiedLinkError: Không thể tải thư viện

static { 
     try { 
      System.loadLibrary("mylib"); 
     } catch (UnsatisfiedLinkError e) { 
      Log.d(TAG, "Unsatisfied Link error: " + e.toString()); 
     } 
    } 

Tôi có kiểm tra mã này trên nhiều thiết bị trong nhà, tôi không gặp phải lỗi này. nhưng từ công bố của tôi, tôi nhận nhật ký với "Gây ra bởi: java.lang.UnsatisfiedLinkError: Không thể tải thư viện". LƯU Ý: Tai nạn này không phổ biến, chỉ có rất ít người gặp phải sự cố này

  • Có vấn đề khi thư viện được đưa vào apk đã xuất? Bây giờ tôi đã đưa thư viện vào /libs/armabi/libmylib.so tự động bằng nhật thực?
  • Có liên quan gì đến phiên bản Android không? Tôi đang hỗ trợ các phiên bản Android kể từ 2.3 (API cấp 9)
  • hoặc tôi có cần tải thư viện từ địa điểm khác không?
  • hoặc tôi thiếu điều gì đó rất quan trọng
  • Có vấn đề với toàn bộ ứng dụng đang được cài đặt trên SDCARD không?

More Info trên tai nạn là: load_segments: 68 thất bại trong việc lập bản đồ phân đoạn từ mylib.so

+0

Tôi có thư viện gốc lớn, lớn đến mức nào? Có lẽ nó không đáp ứng một số yêu cầu bộ nhớ và hệ thống không thể tải. – Blackbelt

+0

~ 7MB (phiên bản gỡ lỗi) – Shri

+0

Đó chắc chắn không phải là vấn đề về bộ nhớ. Trong thiết bị nào bạn đã hết hạn vấn đề này? – Blackbelt

Trả lời

14

Xét rằng ứng dụng của bạn hoạt động một cách chính xác trên hầu hết các thiết bị và chỉ thỉnh thoảng cung cấp cho bạn các lỗi, nó là an toàn để giả định rằng thư viện được đóng gói chính xác trong APK và kích thước/bộ nhớ của nó cũng được chấp nhận.

Vì vậy, tôi sẽ tiếp tục ý thích và đề xuất rằng vấn đề là với kiến ​​trúc xây dựng/biên dịch của thư viện. Hầu hết các thiết bị Android mới hơn đều sử dụng bộ vi xử lý ARM7. Rất có khả năng là thư viện của bạn được biên dịch dựa trên kiến ​​trúc ARM7. Một số thiết bị cũ hơn, đặc biệt là các thiết bị chạy Android 2.3, sử dụng bộ vi xử lý ARM6 (tôi có một thiết bị như vậy mà tôi sử dụng để thử nghiệm - LG GT540 chạy Android 2.3.3), không tương thích về phía trước với kiến ​​trúc ARM7. Tôi đã thấy một sự cố có lỗi tương tự như lỗi bạn chỉ định (load_segments: 68 không thể phân đoạn bản đồ từ mylib.so) khi tôi cố chạy một ứng dụng được thiết kế cho ARM7 trên điện thoại ARM6 cũ của tôi.

Có ba cách để đi xung quanh vấn đề này:

  1. Biên dịch thư viện chống lại cả kiến ​​trúc và bao gồm hai tập tin riêng biệt .so vào apk. Sau đó, tại thời gian chạy xác định loại bộ vi xử lý và tải đúng bộ xử lý. Thành thật mà nói, tôi không biết nếu điều này thậm chí có thể.

  2. Tạo hai tệp apk riêng biệt - một cho ARM6 và một cho ARM7 - sau đó sử dụng bộ lọc trong tệp kê khai để chỉ định kiến ​​trúc tương ứng. Bạn có thể tải cả hai lên Google Play cho cùng một ứng dụng - và các bộ lọc trong tệp kê khai sẽ kiểm soát ứng dụng nào được tải xuống thiết bị nào.

  3. Chỉ hỗ trợ kiến ​​trúc ARM7 bằng cách chỉ định các yêu cầu thiết bị trong tệp kê khai của bạn. Bạn sẽ mất một số đối tượng khách hàng, nhưng sẽ có ít công việc hơn cho chính bạn duy trì hai phiên bản của ứng dụng.

EDIT: Theo tài liệu NDK, nó có thể sản xuất nhiều thư viện cho các kiến ​​trúc khác nhau trong một đi.Bạn có thể kiểm soát đặc biệt mà CPU bạn muốn nhắm mục tiêu bằng cách thêm dòng sau vào file Application.mk:

APP_ABI := arch1 arch2 arch3 ... 

ví dụ,

APP_ABI := armeabi armeabi-v7a mips 

Sau đó, quá trình xây dựng sẽ tạo ra các phiên bản khác nhau của thư viện bản xứ. Các phiên bản này sẽ cần phải được đặt trong gói ứng dụng cuối cùng trong thư mục

lib/<abi>/lib<name>.so 

là tên của kiến ​​trúc. Sau đó, bạn sẽ tải thư viện với

System.loadLibrary("<name>"); 

Hoặc bạn có thể tạo các tệp APK riêng cho từng kiến ​​trúc, sau đó sử dụng chức năng nhiều apk trên google play.

Bạn có thể tìm thấy tất cả thông tin về nhắm mục tiêu kiến ​​trúc trong tệp CPU-ARCH-ABIS.html tệp trong thư mục con docs của NDK.

+0

Nói chung tôi chấp nhận câu trả lời của bạn, tôi nghĩ những gì bạn đang gợi ý là hợp lý. Tuy nhiên tôi không chắc chắn nếu có tùy chọn trong biểu hiện hoặc bất cứ nơi nào tôi có thể xây dựng cụ thể cho amrv6 và armv7, tôi không thể tìm cách sửa lỗi này thông qua tệp kê khai android – Shri

+1

@techjeevi Kiến trúc không được chỉ định trong tệp kê khai apk, nhưng trong xây dựng tệp cho thư viện gốc. Sau đó nó được tích hợp vào ứng dụng xây dựng và được sử dụng bởi google play. Tôi sẽ làm một số đào để tìm một ví dụ. –

+1

@techjeevi Tôi đã cập nhật câu trả lời của mình với các chi tiết về cách nhắm mục tiêu các kiến ​​trúc khác nhau với các phiên bản khác nhau của thư viện gốc cũng như nơi tìm thêm thông tin. –

Các vấn đề liên quan