Chương trình của tôi cần phải giết một ứng dụng cụ thể. Có thể trên một thiết bị, thiết bị chưa được phát hành không? Nếu có - làm thế nào? Tôi biết tên quá trình và PID của nó.Làm thế nào để giết một ứng dụng của bên thứ 3?
Trả lời
Một lần nữa tôi trả lời quá muộn nhưng kể từ khi tôi chạy trên một tình huống tương tự hôm nay tôi đã chia sẻ những phát hiện của mình để giúp đỡ ai đó.
Trước hết, bạn cần phải hiểu những gì bạn có thể giết và những gì không. Theo quan điểm của Android, một ứng dụng không giống như các hệ điều hành khác. Ứng dụng Android bao gồm nhiều thành phần (hoạt động, bộ thu phát sóng, dịch vụ, nhiệm vụ quan trọng nhất, v.v.) được đóng gói trong gói. Một gói có thể có nhiều hơn một tiến trình đang chạy phụ thuộc vào các thành phần của nó đang chạy.
Bây giờ là phần thú vị là một gói phần mềm android không được xem (bằng android) giết hoặc ngừng nếu bất kỳ hoặc tất cả các quá trình của nó đã bị giết, trong thực tế, một gói vẫn có thể chạy ngay cả với không có quy trình chạy hết. Bạn có thể thấy hiệu ứng này nếu bạn khởi động trình mô phỏng, bắt đầu chương trình (tức là Trình duyệt) và sau đó giết quá trình qua DDMS
, sau đó chuyển đến cài đặt gói của ứng dụng (Settings --> Applications --> Manage Applications --> All --> Browser)
, bạn có thể thấy nút Buộc dừng. ứng dụng vẫn đang chạy (từ quan điểm của Android). Điều xảy ra ở đây là ứng dụng có một hoặc nhiều tác vụ bị đóng băng. Tức là, Android đã lưu trạng thái của các hoạt động của ứng dụng (nhiệm vụ hoặc nhiệm vụ) và vì vậy gói vẫn chạy hoặc tốt hơn nếu người dùng quay lại nó, anh ta sẽ đáp ứng điều cuối cùng mà anh ta đang làm. Bây giờ, nếu bạn nhấp vào nút Buộc dừng, Android sẽ hủy tất cả các nhiệm vụ đông lạnh này và khi người dùng quay lại ứng dụng, anh ta sẽ thấy hoạt động đầu tiên. Nhiệm vụ là thứ mà bạn không thể giết (kể từ froyo
) chỉ người dùng (từ nút Buộc), hệ thống hoặc ứng dụng của bên thứ ba được ký bằng cùng một khóa của hệ thống có thể thực hiện điều đó (và có thể là gốc ứng dụng có khả năng nhưng tôi chưa xác nhận điều này). Mặt khác một Process là một cái gì đó bạn có thể giết chết và lấy lại bộ nhớ nó sử dụng, miễn là bạn làm theo một số hạn chế:
- Bạn có sự cho phép
android.permission.KILL_BACKGROUND_PROCESSES
.- Quy trình không phải là hệ thống hoặc quy trình gốc.
- Quy trình không thuộc về thành phần liên tục.
- Quá trình này không quan trọng đối với hệ thống hoạt động bằng bất kỳ phương tiện nào khác.
Bên cạnh quy tắc số 1 bạn không phải làm gì đó về họ, Android sẽ đảm nhiệm việc này.
ActivityManager
có chức năng tiện dụng mà bạn có thể sử dụng để tiêu diệt tất cả các quy trình mà gói có cùng một lúc. Khi bạn gọi nó, Android sẽ giết bất kỳ quá trình có thể bị giết và do đó giải phóng một số bộ nhớ. Tuy nhiên, trạng thái của các nhiệm vụ cho gói này sẽ được lưu lại và khi người dùng quay trở lại ứng dụng, anh ta sẽ thấy điều cuối cùng anh ta làm trừ khi bản thân hệ thống đã giết chúng. Điều này có thể xảy ra vì nó cần tài nguyên hoặc trạng thái đã được lưu lâu rồi (khoảng 30 phút). Tác dụng phụ là bởi vì người dùng đang nghĩ rằng tất cả các ứng dụng giống như trong hệ điều hành máy tính để bàn, họ không tin rằng ứng dụng thực sự bị đóng nhưng đây là cuộc sống với Android.
Bây giờ đến mã:
Đối với dự án của tôi, tôi đã chuẩn bị ba chức năng để đạt được điều này.
Đầu tiên tìm kiếm quy trình đầu tiên pid một gói có thể có và nó trả về -1 nếu không có.
private Context cx;
private ActivityManager am = (ActivityManager) cx.getSystemService(Context.ACTIVITY_SERVICE);
public int findPIDbyPackageName(String packagename) {
int result = -1;
if (am != null) {
for (RunningAppProcessInfo pi : am.getRunningAppProcesses()){
if (pi.processName.equalsIgnoreCase(packagename)) {
result = pi.pid;
}
if (result != -1) break;
}
} else {
result = -1;
}
return result;
}
Điều thứ hai làm điều gì đó ngu ngốc nhưng tôi cần nó cho dự án của mình.
public boolean isPackageRunning(String packagename) {
return findPIDbyPackageName(packagename) != -1;
}
Thứ ba thực hiện công việc.
public boolean killPackageProcesses(String packagename) {
boolean result = false;
if (am != null) {
am.killBackgroundProcesses(packagename);
result = !isPackageRunning(packagename);
} else {
result = false;
}
return result;
}
Họ được xác nhận để làm việc với giả lập API 8 và 9 và trên một thiết bị thực (Galaxy S2) với API 15 và họ DO diệt các tiến trình bất kỳ ứng dụng (không chỉ của riêng bạn) miễn là họ không cần thiết.
Bây giờ về tài liệu android.os.Process.killProcess
mà nói rằng:
... Thông thường điều này có nghĩa là chỉ quá trình chạy của người gọi gói/ứng dụng và bất kỳ quy trình thêm được tạo ra bởi ứng dụng đó; ...
Tôi tin rằng "quá trình chạy gói/ứng dụng của người gọi" nghĩa là ứng dụng trình khởi chạy tại nhà và KHÔNG phải là ứng dụng của riêng bạn. Ứng dụng của bạn là người gọi và quá trình chạy gói/ứng dụng của người gọi là trình khởi chạy trang chủ hoặc bất kỳ ứng dụng nào khác đã khởi chạy ứng dụng của bạn. Đây là cách duy nhất để tôi giải thích rằng hàm killBackgroundProcesses
và hàm android.os.Process.killProcess
thực sự hoạt động trên các ứng dụng của bên thứ ba.
Cảm ơn bạn đã trả lời đầy đủ! –
Giải thích rõ ràng .. –
đứng ở doc:
Giết quá trình với PID nhất định. Lưu ý rằng, mặc dù API này cho phép chúng ta yêu cầu để giết bất kỳ quá trình nào dựa trên PID của nó, hạt nhân vẫn sẽ áp đặt các hạn chế tiêu chuẩn trên các PID mà bạn thực sự có thể giết. Thông thường, điều này có nghĩa là chỉ có quá trình chạy gói/ứng dụng của người gọi và bất kỳ quy trình bổ sung nào được tạo bởi ứng dụng đó; các gói chia sẻ một UID chung cũng sẽ có thể giết chết các quy trình của nhau.
vì vậy bạn có thể giết chết quá trình của riêng bạn ..
xem tài liệu Process. Tôi đã cố gắng chạy adb shell kill pid
nhưng nó yêu cầu quyền người dùng siêu
thử http://stackoverflow.com/a/40266343/5235263 – benbas1982