2009-06-16 30 views
15

Tôi đang phát triển thư viện dành cho Android yêu cầu cập nhật thường xuyên từ máy chủ trung tâm. Tôi đã nghĩ nó tuyệt vời như thế nào nếu thư viện của tôi có thể tự cập nhật - hoặc nếu tôi có thể phát hành thư viện bootstrap để tải xuống thư viện đích khi ứng dụng được cài đặt.Tải mã từ xa Android

Tôi thấy lớp này có tên là 1,5 "DexClassLoader" nhưng dường như có chút quý giá trên web bên cạnh tài liệu API. Có ai sử dụng thành công cho kịch bản mà tôi mô tả?

Ngoài ra, các điều khoản của Android Market có cho phép một điều như vậy không?

Trả lời

13

Tôi đã sử dụng thành công DexClassLoader. Điều quan trọng là cung cấp dexOutputDir thực sự có thể ghi bởi ứng dụng của bạn, vì vậy không phải/data/dalvik-cache. Nếu không, nhật ký sẽ hiển thị một hoặc hai dòng về việc không viết ở đó, theo sau là ClassNotFoundException.

cl = new DexClassLoader("/full/path/com.example.apk", 
         getFilesDir().getAbsolutePath(),// /data/data/foo/files 
         null, // native lib path, I haven't used this 
         MyClass.class.getClassLoader()); 
// This doesn't make Class.forName() work, instead I do this: 
Class<?> foo = cl.loadClass("com.example.foo"); 

Để làm Class.forName() hoạt động, bạn có thể thử Thread.setContextClassLoader() (Tôi chưa).

+0

Xin chào bạn có thể xin vui lòng thêm mã nguồn hoàn chỉnh. Nó sẽ là một trợ giúp tuyệt vời. Cảm ơn trước. –

+1

nó không hoạt động đối với kẹo Android5 trở lên vì ART: http://stackoverflow.com/questions/27349097/load-dex-file-dynamically-on-android-5-0 – gturedi

3

Thực tế những gì bạn muốn được hỗ trợ và hoạt động. DexClassLoader không hoạt động như mong đợi đối với tôi, nhưng mã sau hoạt động tốt.

DexFile df = new DexFile(new File("/data/app/my_downloaded_lib.apk")); 
ClassLoader cl = getClassLoader(); 
Class clazz = df.loadClass("com/my/lib/MyClass", cl); 

Về câu hỏi thị trường, tôi không thấy bất kỳ vấn đề nào với điều này, nhưng bạn phải đọc EULA để chắc chắn.

+0

Tác phẩm này, nhưng làm cho đối tượng Tệp phản tác dụng: DexFile sẽ lấy đường dẫn và tự mở nó. Bạn có thể sử dụng hàm tạo có một đường dẫn String. –

+0

Xin chào, có thể bạn đã đúng, nhưng khi tôi trả lời, đây là cách duy nhất nó hoạt động. –

2

DexClassLoader là câu trả lời đúng. Ứng dụng không bao giờ nên sử dụng trực tiếp DexFile (nó có nghĩa là để được sử dụng bởi bộ tải lớp).

Bạn có thể sử dụng bộ nhớ ngoài (/sdcard) hoặc vùng dữ liệu riêng của ứng dụng, cho thông số dexOutputDir. Bộ nhớ ngoài thường lớn hơn, nhưng nếu thẻ bị đẩy ra, ứng dụng của bạn sẽ bị xóa và do thiếu sự cho phép của tệp, việc thay thế mã của bạn trở nên dễ dàng đối với bên thứ ba. Điều này có thể cho phép các ứng dụng độc hại làm cho ứng dụng của bạn thực hiện các hành động tùy ý. (Nếu bạn muốn làm điều đó dù sao, lấy đường dẫn qua Environment.getExternalStorageDirectory();. Đòi hỏi sự cho phép WRITE_EXTERNAL_STORAGE)

Diện tích dữ liệu app-private (lấy đường dẫn từ Context.getFilesDir()) là an toàn hơn, và cũng có lợi thế là được làm sạch tự động nếu ứng dụng được gỡ cài đặt. Đây là cách tiếp cận được khuyến nghị.

+4

Tôi cũng nghĩ rằng việc tải mã xuống thẻ SD sẽ có phần không an toàn. – CommonsWare

+0

KHÔNG BAO GIỜ ghi tệp dex của bạn vào đường dẫn Thẻ SD. Điều này sẽ tạo ra một lỗ hổng bảo mật. http://www.symantec.com/connect/blogs/android-class-loading-hijacking – ajma

+0

Được cập nhật để giải quyết các vấn đề về bảo mật. – fadden

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