Tôi đã trả lời câu hỏi tương tự here mà bạn có thể muốn xem qua. Tôi sẽ cung cấp cho các phân tích về cách tôi nghĩ rằng bạn có thể giải quyết vấn đề này cụ thể mặc dù.
Sử dụng một bối cảnh tĩnh từ lớp Application
Phương pháp này sẽ làm việc nhưng tôi không ngây thơ của nó. Nó làm cho thử nghiệm khó hơn và kết hợp mã của bạn với nhau.
public class App extends Application {
private static Context context;
public static Context getContext() {
return context;
}
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
}
Sau đó, trong MainModel của bạn:
public class MainModel {
public List<String> getListOfAllApps(){
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List<ResolveInfo> pkgAppsList = App.getContext().getPackageManager().queryIntentActivities(mainIntent, 0);
List<String> results = new ArrayList<>();
for (ResolveInfo app : pkgAppsList) {
results.add(app.resolvePackageName);
}
return results;
}
}
Bây giờ chúng tôi đã có mà ra đường đi, chúng ta hãy xem xét một số lựa chọn tốt hơn.
Do nó trong các Hoạt động
Vì vậy, hoạt động của bạn thực hiện Xem của bạn. Nó có thể làm một vài thứ Anrdoidy quá như onActivityResult. Có một cuộc tranh cãi để giữ mã Android trong hoạt động và chỉ truy cập nó qua Xem giao diện:
public interface MainView {
List<String> getListOfAllApps();
}
Các Hoạt động:
public class MainActivity extends BaseActivity implements MainView {
//..
@Override
public List<String> getListOfAllApps(){
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List<ResolveInfo> pkgAppsList = getPackageManager().queryIntentActivities(mainIntent, 0);
List<String> results = new ArrayList<>();
for (ResolveInfo app : pkgAppsList) {
results.add(app.resolvePackageName);
}
return results;
}
//..
}
Và Người trình bày:
public class MainPresenter extends BasePresenter {
public void onSendButtonClick(){
view.getListOfAllApps();
}
}
Tóm tắt các chi tiết trong một lớp riêng biệt
Trong khi tùy chọn cuối cùng không phá vỡ các quy tắc của MVP nó không cảm thấy khá đúng khi nhận được một danh sách các gói không phải là thực sự một hoạt động Xem. Tùy chọn ưa thích của tôi là ẩn sử dụng Ngữ cảnh phía sau một giao diện/lớp.
Tạo một lớp PackageModel
(hoặc bất kỳ tên có ưa thích của bạn):
public class PackageModel {
private Context context;
public PackageModel(Context context) {
this.context = context;
}
public List<String> getListOfAllApps(){
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List<ResolveInfo> pkgAppsList = context.getPackageManager().queryIntentActivities(mainIntent, 0);
List<String> results = new ArrayList<>();
for (ResolveInfo app : pkgAppsList) {
results.add(app.resolvePackageName);
}
return results;
}
}
Bây giờ có Presenter của bạn yêu cầu này như một tham số constructor:
public class MainPresenter extends BasePresenter {
private PackageModel packageModel;
public MainPresenter(PackageModel packageModel) {
this.packageModel = packageModel;
}
public void onSendButtonClick(){
packageModel.getListOfAllApps();
}
}
Cuối cùng trong hoạt động của bạn:
public class MainActivity extends BaseActivity implements MainView {
private MainPresenter presenter;
private void createPresenter() {
PackageModel packageModel = new PackageModel(this);
presenter = new MainPresenter(packageModel);
presenter.addView(this);
}
}
Giờ việc sử dụng Ngữ cảnh bị ẩn khỏi Trình dẫn và nó c mang theo mà không có bất kỳ kiến thức nào về Android. Điều này được gọi là tiêm constructor. Nếu bạn đang sử dụng một khuôn khổ tiêm phụ thuộc, nó có thể xây dựng tất cả các phụ thuộc cho bạn.
Nếu bạn muốn bạn có thể tạo giao diện cho PackageModel nhưng tôi không nghĩ rằng nó thực sự cần thiết như một khuôn khổ nhạo báng như Mockito có thể tạo ra một nhánh mà không cần sử dụng giao diện.
Bạn không có 'Lớp ứng dụng'? –
Tôi có lớp application.but làm thế nào để sử dụng nó.Bạn có nói rằng sử dụng một số trường liên tục cho bối cảnh để sử dụng trong lớp ứng dụng? Vấn đề là theo mô hình chúng ta không nên sử dụng bất kỳ lớp/đối tượng cụ thể trong mô hình Android. –
Không hề. Chỉ cần tạo applicationContext trong onCreate (...) và sử dụng nó –