Một Application
lớp mở rộng có thể khai báo các biến toàn cục. Có những lý do khác?
Một Application
lớp mở rộng có thể khai báo các biến toàn cục. Có những lý do khác?
Câu trả lời:
Trực tiếp, tôi không thể nghĩ ra một kịch bản thực tế trong đó việc mở rộng Ứng dụng hoặc là thích hợp hơn với cách tiếp cận khác hoặc cần thiết để thực hiện một cái gì đó. Nếu bạn có một đối tượng đắt tiền, được sử dụng thường xuyên, bạn có thể khởi tạo nó trong IntentService khi bạn phát hiện ra rằng đối tượng hiện không có mặt. Bản thân ứng dụng chạy trên luồng UI, trong khi IntentService chạy trên luồng của chính nó.
Tôi thích truyền dữ liệu từ Hoạt động sang Hoạt động với Ý định rõ ràng hoặc sử dụng SharedPreferences. Cũng có nhiều cách để truyền dữ liệu từ Fragment sang Activity gốc của nó bằng các giao diện.
"prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences"
. Chúng ta nên luôn luôn loại bỏ trạng thái toàn cầu nhiều nhất có thể và sử dụng các công cụ Android tiêu chuẩn để quản lý trạng thái toàn cầu thay vì các vars / singletons tĩnh, v.v.
apk
tệp trong điện thoại di động của mình, nó bao gồm nhiều khối hữu ích như, Activity
s, Service
s và các khối khác.Application
bất kể Activity
người dùng đang sử dụng,Application
,Cursor
và đóng nó nhiều lần không hiệu quả,Intent
s để truyền dữ liệu nhưng vụng về và bản thân hoạt động có thể không tồn tại ở một kịch bản nhất định tùy thuộc vào bộ nhớ khả dụng.Application
,Application
để bắt đầu một số thứ nhất định như phân tích, v.v. vì lớp ứng dụng được khởi động trước khi Activity
s hoặc
Services
s đang được chạy,Lớp ứng dụng là đối tượng có vòng đời đầy đủ của ứng dụng của bạn. Đây là lớp cao nhất của bạn như là một ứng dụng. ví dụ sử dụng có thể:
Bạn có thể thêm những gì bạn cần khi ứng dụng được khởi động bằng cách ghi đè onCreate trong lớp Ứng dụng.
lưu trữ các biến toàn cục nhảy từ Hoạt động này sang Hoạt động khác. Giống như Asynctask.
Vân vân
Đôi khi bạn muốn lưu trữ dữ liệu, như các biến toàn cục cần được truy cập từ nhiều Hoạt động - đôi khi ở mọi nơi trong ứng dụng. Trong trường hợp này, đối tượng Ứng dụng sẽ giúp bạn.
Ví dụ: nếu bạn muốn nhận dữ liệu xác thực cơ bản cho từng yêu cầu http , bạn có thể triển khai các phương thức cho dữ liệu xác thực trong đối tượng ứng dụng.
Sau này, bạn có thể lấy tên người dùng và mật khẩu trong bất kỳ hoạt động nào như thế này:
MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();
Và cuối cùng, hãy nhớ sử dụng đối tượng Ứng dụng làm đối tượng đơn lẻ:
public class MyApplication extends Application {
private static MyApplication singleton;
public MyApplication getInstance(){
return singleton;
}
@Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}
Để biết thêm thông tin, xin vui lòng bấm vào Lớp ứng dụng
Lớp Ứng dụng là một singleton mà bạn có thể truy cập từ bất kỳ hoạt động nào hoặc bất kỳ nơi nào khác mà bạn có một đối tượng Ngữ cảnh.
Bạn cũng có được một chút vòng đời.
Bạn có thể sử dụng phương thức onCreate của Ứng dụng để khởi tạo các đối tượng đắt tiền nhưng được sử dụng thường xuyên như trình trợ giúp phân tích. Sau đó, bạn có thể truy cập và sử dụng các đối tượng ở khắp mọi nơi.
Sử dụng tốt nhất các lớp ứng dụng. Ví dụ: Giả sử bạn cần khởi động lại trình quản lý báo thức khi khởi động xong.
public class BaseJuiceApplication extends Application implements BootListener {
public static BaseJuiceApplication instance = null;
public static Context getInstance() {
if (null == instance) {
instance = new BaseJuiceApplication();
}
return instance;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onBootCompleted(Context context, Intent intent) {
new PushService().scheduleService(getInstance());
//startToNotify(context);
}
Không phải là một câu trả lời mà là một quan sát : hãy nhớ rằng dữ liệu trong đối tượng ứng dụng mở rộng không nên được gắn với một thể hiện của một hoạt động, vì có thể bạn có hai phiên bản của cùng một hoạt động chạy cùng một lúc (một trong tiền cảnh và một không nhìn thấy được) .
Ví dụ: bạn bắt đầu hoạt động bình thường thông qua trình khởi chạy, sau đó "thu nhỏ" nó. Sau đó, bạn bắt đầu một ứng dụng khác (ví dụ: Trình tác vụ) khởi động một phiên bản khác của activitiy của bạn, ví dụ để tạo lối tắt, vì ứng dụng của bạn hỗ trợ android.intent.action.CREATE_SHORTCUT. Nếu lối tắt sau đó được tạo và lệnh gọi hoạt động tạo lối tắt này đã sửa đổi dữ liệu của đối tượng ứng dụng, thì hoạt động đang chạy trong nền sẽ bắt đầu sử dụng đối tượng ứng dụng đã sửa đổi này khi nó được đưa trở lại nền trước.
Tôi thấy rằng câu hỏi này đang thiếu một câu trả lời. Tôi mở rộng Application
vì tôi sử dụng triển khai Bill Pugh Singleton ( xem tài liệu tham khảo ) và một số người độc thân của tôi cần bối cảnh. Các Application
hình lớp như thế này:
public class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
private static MyApplication sInstance;
@Contract(pure = true)
@Nullable
public static Context getAppContext() {
return sInstance;
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() called");
sInstance = this;
}
}
Và những người độc thân trông như thế này:
public class DataManager {
private static final String TAG = DataManager.class.getSimpleName();
@Contract(pure = true)
public static DataManager getInstance() {
return InstanceHolder.INSTANCE;
}
private DataManager() {
doStuffRequiringContext(MyApplication.getAppContext());
}
private static final class InstanceHolder {
@SuppressLint("StaticFieldLeak")
private static final DataManager INSTANCE = new DataManager();
}
}
Bằng cách này, tôi không cần phải có ngữ cảnh mỗi khi tôi sử dụng một singleton và được khởi tạo đồng bộ hóa lười biếng với số lượng mã tối thiểu.
Mẹo: cập nhật mẫu singleton của Android Studio tiết kiệm rất nhiều thời gian.
Tôi nghĩ rằng bạn có thể sử dụng lớp Ứng dụng cho nhiều thứ, nhưng tất cả chúng đều gắn liền với nhu cầu của bạn để thực hiện một số thứ TRƯỚC KHI bất kỳ Hoạt động hoặc Dịch vụ nào của bạn được bắt đầu. Ví dụ, trong ứng dụng của tôi, tôi sử dụng phông chữ tùy chỉnh. Thay vì gọi
Typeface.createFromAsset()
từ mọi Hoạt động để lấy tham chiếu cho phông chữ của tôi từ thư mục Tài sản (điều này rất tệ vì nó sẽ dẫn đến rò rỉ bộ nhớ vì bạn đang giữ tham chiếu đến tài sản mỗi khi bạn gọi phương thức đó), tôi thực hiện điều này từ onCreate()
phương thức trong lớp Ứng dụng của mình :
private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
super.onCreate();
appInstance = this;
quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
"fonts/Quicksand-Regular.otf");
...
}
Bây giờ, tôi cũng có một phương thức được định nghĩa như thế này:
public static App getAppInstance() {
return appInstance;
}
và điều này:
public Typeface getQuickSandRegular() {
return quicksandRegular;
}
Vì vậy, từ bất cứ nơi nào trong ứng dụng của tôi, tất cả những gì tôi phải làm là:
App.getAppInstance().getQuickSandRegular()
Một cách sử dụng khác cho lớp Ứng dụng đối với tôi là kiểm tra xem thiết bị có được kết nối với Internet TRƯỚC các hoạt động và dịch vụ yêu cầu kết nối thực sự bắt đầu và thực hiện các hành động cần thiết hay không.
Nguồn: https://github.com/codepath/android_guides/wiki/Under Hiểu-the-Assroid-Ứng dụng-Kính
Trong nhiều ứng dụng, không cần phải làm việc trực tiếp với lớp ứng dụng. Tuy nhiên, có một vài cách sử dụng được chấp nhận của một lớp ứng dụng tùy chỉnh:
- Các tác vụ chuyên biệt cần chạy trước khi tạo hoạt động đầu tiên của bạn
- Khởi tạo toàn cầu cần được chia sẻ trên tất cả các thành phần (báo cáo sự cố, sự tồn tại)
- Các phương thức tĩnh để dễ dàng truy cập vào dữ liệu bất biến tĩnh như đối tượng máy khách mạng chung
Bạn không bao giờ nên lưu trữ dữ liệu cá thể có thể thay đổi bên trong đối tượng Ứng dụng vì nếu bạn cho rằng dữ liệu của mình sẽ ở đó, ứng dụng của bạn chắc chắn sẽ gặp sự cố tại một số điểm với NullPulumException. Đối tượng ứng dụng không được đảm bảo ở lại trong bộ nhớ mãi mãi, nó sẽ bị giết. Trái với suy nghĩ của nhiều người, ứng dụng sẽ không được khởi động lại từ đầu. Android sẽ tạo một đối tượng Ứng dụng mới và bắt đầu hoạt động mà người dùng trước đó đã ảo tưởng rằng ứng dụng này không bao giờ bị giết ngay từ đầu.
Bạn có thể truy cập các biến vào bất kỳ lớp nào mà không cần tạo đối tượng, nếu nó được mở rộng bởi Ứng dụng. Chúng có thể được gọi trên toàn cầu và trạng thái của chúng được duy trì cho đến khi ứng dụng không bị giết.
Việc sử dụng ứng dụng mở rộng chỉ làm cho ứng dụng của bạn chắc chắn cho bất kỳ loại hoạt động nào bạn muốn trong suốt thời gian chạy ứng dụng. Bây giờ nó có thể là bất kỳ loại biến nào và giả sử nếu bạn muốn tìm nạp một số dữ liệu từ máy chủ thì bạn có thể đặt asynctask của mình vào ứng dụng để nó sẽ tìm nạp mỗi lần và liên tục, để bạn sẽ tự động nhận được dữ liệu cập nhật .. Sử dụng liên kết này để có thêm kiến thức ....
http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android
Để thêm vào các câu trả lời khác nói rằng bạn có thể muốn lưu trữ các biến trong phạm vi ứng dụng, cho mọi luồng xử lý dài hoặc các đối tượng khác cần liên kết với ứng dụng của bạn khi bạn KHÔNG sử dụng một hoạt động (ứng dụng không phải là một hoạt động) .. chẳng hạn như không thể yêu cầu một dịch vụ bị ràng buộc .. sau đó ràng buộc với thể hiện của ứng dụng được ưu tiên. Cảnh báo rõ ràng duy nhất với phương pháp này là các đối tượng tồn tại miễn là ứng dụng còn sống, do đó cần phải kiểm soát nhiều bộ nhớ hơn nếu không bạn sẽ gặp phải các vấn đề liên quan đến bộ nhớ như rò rỉ.
Một thứ khác mà bạn có thể thấy hữu ích là theo thứ tự các thao tác, ứng dụng sẽ khởi động trước khi có bất kỳ hoạt động nào. Trong khung thời gian này, bạn có thể chuẩn bị bất kỳ công việc vệ sinh cần thiết nào sẽ xảy ra trước hoạt động đầu tiên của bạn nếu bạn muốn.
2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created