Xử lý conflict thư viện phụ thuộc bằng gradle trong Android
Direct vs Transitive Transitive dependency cho phép dự án của bạn phụ thuộc vào các thư viện mà thư viện đó lại phụ thuộc vào các thư viện khác. Kết quả là một cây phụ thuộc. Những cây này có xu hướng trở nên phức tạp vì dự án của bạn cần nhiều thư viện hơn để biên dịch. Direct dependency là các ...
Direct vs Transitive
Transitive dependency cho phép dự án của bạn phụ thuộc vào các thư viện mà thư viện đó lại phụ thuộc vào các thư viện khác. Kết quả là một cây phụ thuộc. Những cây này có xu hướng trở nên phức tạp vì dự án của bạn cần nhiều thư viện hơn để biên dịch. Direct dependency là các thư viện mà coder import vào dự án.
Khám phá dependency tree
Bây giờ chúng ta hãy nhìn vào toàn bộ cây phụ thuộc của dự án.
Gọi lệnh :
./gradlew dependencies app:dependencies --configuration compile
kết quả ra cái gì đó tương tự như thế này:
Chúng ta có thể thấy rằng dự án này có rất nhiều conflicts về sự phụ thuộc. Những cái được đánh dấu kiểu
{library name}: {required version} -> {version thực tế}
Dependency conflicts
Điều rất phổ biến đối với các mô-đun và thư viện khác nhau để chia sẻ cùng một sự phụ thuộc. Vấn đề phát sinh khi sự phụ thuộc giống nhau, nhưng mỗi mô-đun hoặc thư viện đều cần một phiên bản khác. Điều này khiến cho dự án chứa nhiều phiên bản của cùng một class, và lần lượt làm cho Dex tool thất bại với lỗi sau:
com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry:
Resolving conflicts
Kiểm soát các dự án phụ thuộc
- Không chạy trên phiên bản xung đột
Thêm đoạn code sau vào file build.gradle dự án của bạn.
configurations.all { resolutionStrategy { failOnVersionConflict() } }
- Ép buộc một sự phụ thuộc cụ thể
Ví dụ sau ép asm-all 3.3.1 , commomns-io 1.4 , và bolts mới nhất có số phiên bản chính là 1 (ví dụ: bolts 1.x):
configurations.all { resolutionStrategy { force 'asm:asm-all:3.3.1', 'commons-io:commons-io:1.4', 'com.parse.bolts:bolts-android:1.+' } }
- Ưu tiên các mô-đun riêng
Luôn luôn ưu tiên các module riêng:
configurations.all { resolutionStrategy { preferProjectModules() } }
Ví dụ sau thay thế tất cả các instances của commons-io với một mô-đun tùy chỉnh my-commons-io :
configurations.all { resolutionStrategy { dependencySubstitution { substitute module('commons-io:commons-io:2.4') with project(':my-commons-io') } } }
Kiểm soát phụ thuộc cụ thể
Bạn cũng có thể tinh chỉnh các thiết lập của bạn để một sự phụ thuộc cụ thể vào một dự án cụ thể.
- Không tính phụ thuộc tạm thời
Việc thêm thẻ này vào thẻ phụ thuộc của bạn sẽ thêm vào thư viện appcompat-v7 nhưng không có phụ thuộc riêng của nó. Bạn sẽ phải đảm bảo rằng tất cả các thư viện cần thiết được thêm vào bằng cách thêm các phụ thuộc trực tiếp hoặc bằng cách dựa vào các phụ thuộc tạm thời được tham chiếu bởi các mô đun khác:
dependencies { compile('com.android.support:appcompat-v7:23.1.0') { transitive = false } }
Mặc định cho transitive là true .
Bạn cũng có thể loại trừ các phụ thuộc tạm thời cụ thể.
Ví dụ sau loại trừ thư viện bolts khỏi bị thêm vào, nếu cần thiết bởi appcompat :
dependencies { compile('com.android.support:appcompat-v7:23.1.0') { exclude group: 'com.parse.bolts' } }
Ép buộc một phiên bản cụ thể
Điều này bắt buộc dự án của bạn sử dụng trên bolts phiên bản 1.1:
dependencies { compile('com.parse.bolts:bolts-android:1.+') { force = true } }