2012-03-18 22 views
13

Tôi đang tạo một dự án thư viện cho một số ứng dụng Android. Tất cả các ứng dụng đều có một số chức năng phổ biến mà tôi muốn đưa vào dự án thư viện nhưng các chức năng của dự án thư viện yêu cầu sử dụng các hằng số cụ thể của ứng dụngAndroid, Cách tốt nhất để cung cấp các hằng số ứng dụng cụ thể trong một dự án thư viện?

Vì vậy, tôi đang tìm cách cung cấp các chức năng thư viện với tên của các hằng số và cho phép từng ứng dụng để định nghĩa chúng

một ví dụ về một hằng số ứng dụng cụ thể và làm thế nào nó được sử dụng trong dự án thư viện

public class AppConstants { 
    public static final long APP_ID = 6;//Needs to be set for each app 
} 

public static long getCurrentAppId(Context context) { 
    return getLongPreference(context, CURRENT_APP_ID_KEY, AppConstants.APP_ID); 
} 

Đây chỉ là một ví dụ về khoảng 60 hằng số mà cần phải được xác định cho mỗi ứng dụng cho một số lượng lớn các chức năng thư viện

Rõ ràng tôi sẽ thường chỉ nhập khẩu/include file app_constants.java cụ thể dự án nhưng điều này là không thể thực hiện trong các tập tin dự án thư viện như nó đã không có một đầu mối về các ứng dụng cụ thể (đúng như vậy)

Vì vậy, cách tốt nhất để có mỗi ứng dụng cụ thể ghi đè các hằng số là gì?

Cập nhật Tôi mất nhiều thời gian để quyết định câu trả lời tuyệt vời nào phù hợp nhất với nhu cầu của tôi (Cảm ơn mọi người) Cuối cùng tôi đã chọn giải pháp xml. Tôi không đặc biệt thích nó vì nó clutters lên nguồn ứng dụng của tôi và tôi đã nghiêm túc xem xét việc sử dụng giải pháp giao diện nhưng giải pháp xml không làm việc độc đáo

Trả lời

20

Lựa chọn # 1 Mở rộng lớp AppConstants của bạn trong mỗi dự án

tốt hơn Một Option # 2 nguồn lực sử dụng XML để định nghĩa hằng

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
<item type="integer" name="app_id" format="integer">6</item> 
</resources> 

sau đó bạn có thể lấy chúng bằng cách

Context.getResources().getInteger(R.integer.app_id); 

thêm tệp xml vào tài nguyên của bạn trong mỗi dự án chỉ với các giá trị bạn cần khác nhau

+2

Nếu bạn xác định các nguồn lực với cùng id trong thư viện của bạn và ứng dụng của bạn, bạn nhận được giá trị từ ứng dụng nếu tồn tại, từ thư viện khác. Vì vậy, đó là một cách tiếp cận thực sự tốt đẹp cho các giá trị bạn muốn ghi đè lên mỗi ứng dụng. Vì nó sử dụng hệ thống tài nguyên, bạn thậm chí có thể thực hiện các giá trị cho mỗi cấu hình (landscape vs portrait etc) – zapl

1

xác định chúng như của enum trong dự án thư viện của bạn, giống như

public enum Planet { MERCURY, VENUS, MARS } 

android thích mất cách tiếp cận khác, sợ hãi liên tục giao diện, như,

interface Planets { 
    static final int MERCURY = 1; 
    static final int VENUS = 2; 
    ... 
} 
tuy nhiên

, đây là một java nổi tiếng chống mẫu (giao diện không đổi, và được bao phủ i n chi tiết trong Java hiệu quả, tôi trích dẫn,

Mẫu giao diện không đổi là giao diện người dùng kém. Đó là một lớp học sử dụng một số hằng số bên trong là một chi tiết thực hiện. Việc triển khai giao diện không đổi khiến chi tiết triển khai này bị rò rỉ vào API được xuất của lớp học. Không có hậu quả gì đối với người dùng của một lớp mà lớp đó triển khai một giao diện không đổi. Trong thực tế , nó thậm chí có thể gây nhầm lẫn cho chúng. Tồi tệ hơn, nó thể hiện cam kết: nếu trong bản phát hành trong tương lai, lớp đó sẽ được sửa đổi để không còn cần để sử dụng hằng số, nó vẫn phải triển khai giao diện để đảm bảo khả năng tương thích nhị phân . Nếu một lớp nonfinal thực hiện một giao diện không đổi, tất cả các lớp con của nó sẽ có các không gian tên của chúng bị ô nhiễm bởi các hằng số trong giao diện.

nếu bạn cần các hằng số có giá trị int đối với một số lý do, và kêu gọi toString() trên enum là không đủ, bạn có thể cung cấp cho các enum là một thông tin thêm như,

public enum ZipCode { 
    LYNNWOOD(98036), SAN_JOSE(95112), ...; 

    private int zipCode; 

    private ZipCode(int zipCode) { this.zipCode = zipCode; } 

    public int getZipCode() { return zipCode; } 
} 

Note rằng enum của hơi kém hiệu suất hơn so với hằng số nguyên, nhưng từ một tổ chức mã và quan điểm rõ ràng họ là cao cấp hơn.

3

Tôi không biết của một lược đồ tuyệt vời để làm điều đó nhưng chắc chắn nó sẽ làm việc theo cách này:

xác định một số lớp cơ sở trong thư viện

// class, enum or whatever you want it to be. 
class BaseConstants { 
    // use some real singleton instead 
    public static final BaseConstants instance = new BaseConstants(); 

    // define those values - sadly static inheritance does not work 
    private static final int APP_ID = 0; 
    private static final int CURRENT_APP_ID_KEY = 24; 

    // so we have to do that via methods 
    protected int getAppId() { 
     return APP_ID; 
    } 
    protected int getAppIdKey() { 
     return CURRENT_APP_ID_KEY; 
    } 
} 

của bạn cho mỗi Hoạt động mà muốn một cái gì đó thực hiện tùy chỉnh rằng

class App1Constants extends BaseConstants { 
    public static final App1Constants instance = new App1Constants(); 

    private final static int APP_ID = 1; 

    // want a different APP_ID here. 
    protected int getAppId() { 
     return APP_ID; 
    } 

    // getAppIdKey not implemented here, uses default 
} 

Sử dụng mà lớp làm ngữ cảnh cho các hằng số cho thư viện của bạn

class Library { 
    public static long getCurrentAppId(Context context, BaseConstants settings) { 
     return getLongPreference(context, settings.getAppIdKey(), settings.getAppId()); 
    } 
} 

hoạt động sẽ là như vậy

class myActivity extends Activity { 
    // each Activity can implement it's own constants class and overwrite only some values 
    private static final BaseConstants CONSTANTS = App1Constants.instance; 

    private void whatever() { 
     long appId = Library.getCurrentAppId(this, CONSTANTS); 
    } 
} 

class myActivity2 extends Activity { 
    // or could just use the default ones 
    private static final BaseConstants CONSTANTS = BaseConstants.instance; 

    private void whatever() { 
     long appId = Library.getCurrentAppId(this, CONSTANTS); 
    } 
} 

schema Đó là loại xấu xí nhưng nó sẽ làm việc ít nhất

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