Ghi đè nút quay lại để hoạt động như nút home


253

Khi nhấn nút quay lại, tôi muốn ứng dụng của mình chuyển sang trạng thái dừng, thay vì trạng thái bị phá hủy.

Trong tài liệu Android có ghi:

... Không phải tất cả các hoạt động đều có hành vi bị phá hủy khi nhấn BACK. Khi người dùng bắt đầu phát nhạc trong ứng dụng Nhạc và sau đó nhấn BACK, ứng dụng sẽ ghi đè hành vi trở lại bình thường, ngăn hoạt động của người chơi bị phá hủy và tiếp tục phát nhạc, mặc dù hoạt động của nó không còn hiển thị

Làm cách nào để sao chép chức năng này trong ứng dụng của riêng tôi?

Tôi nghĩ rằng phải có ba khả năng ...

  1. Giữ nút quay lại nhấn (như bên dưới) và sau đó gọi bất kỳ phương thức nào (s) gọi nút home.

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            Log.d(this.getClass().getName(), "back button pressed");
        }
        return super.onKeyDown(keyCode, event);
    }
  2. Chụp nút quay lại và sau đó giả mạo nhấn nút home.

  3. Nhấn nút quay lại, sau đó bắt đầu Hoạt động của màn hình chính, đưa Hoạt động của ứng dụng của tôi vào trạng thái dừng một cách hiệu quả.

Chỉnh sửa: Tôi biết về các dịch vụ và đang sử dụng một trong ứng dụng mà vấn đề này có liên quan. Câu hỏi này cụ thể là về việc đưa Activity vào trạng thái dừng chứ không phải trạng thái bị hủy khi nhấn nút quay lại.


xem một câu trả lời tương tự stackoverflow.com/questions/5914040/
Khăn

Câu trả lời:


338

Hầu hết thời gian bạn cần tạo Dịch vụ để thực hiện một cái gì đó trong nền và hiển thị của bạn Activitychỉ đơn giản là kiểm soát điều này Service. (Tôi chắc chắn Trình phát nhạc hoạt động theo cùng một cách, vì vậy ví dụ trong tài liệu có vẻ hơi sai lệch.) Nếu đó là trường hợp, thì bạn Activitycó thể finishnhư bình thường và Servicevẫn sẽ chạy.

Một cách tiếp cận đơn giản hơn là chụp Backnút nhấn và gọi moveTaskToBack (đúng) như sau:

// 2.0 and above
@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

// Before 2.0
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

Tôi nghĩ rằng tùy chọn ưu tiên nên dành cho một Hoạt động để kết thúc bình thường và có thể tự tạo lại, ví dụ như đọc trạng thái hiện tại từ Dịch vụ nếu cần. Nhưng moveTaskToBackcó thể được sử dụng như là một thay thế nhanh chóng trong dịp.

LƯU Ý : như được Dave chỉ ra bên dưới Android 2.0 đã giới thiệu một onBackPressedphương pháp mới và những khuyến nghị này về cách xử lý nút Quay lại.


1
moveTaskToBack () dường như hoạt động như mong muốn. Nhược điểm có thể là gì khi sử dụng phương pháp này? Có trường hợp nào điều này có thể không hoạt động như mong đợi?
bdls

1
Sau khi đọc tài liệu của nó cẩn thận hơn, tôi thực sự nghĩ rằng nó sẽ hoạt động tốt. (Ban đầu tôi nghĩ nó được áp dụng cho hoạt động, nhưng thực tế nó nói rằng "nhiệm vụ có chứa hoạt động này".) Nhưng tất nhiên bạn nên tự mình kiểm tra nó. :)
Mirko N.

Cảm ơn Mirko, phương pháp có vẻ hoạt động tốt. Sẽ thật tuyệt nếu bạn đưa ra sự nổi bật hơn cho bản chỉnh sửa của bạn ở cuối câu trả lời cho những người nhìn vào câu hỏi này sau - vì đó là thứ tôi đang tìm kiếm!
bdls

4
Vui lòng đọc android-developers.blogspot.com/2009/12/ Khăn để biết cách được đề xuất để xử lý phím quay lại.
hackbod

1
Về mặt lý thuyết, @bdls hoạt động nền của bạn có thể bị hệ thống tiêu diệt nếu nó thiếu tài nguyên, vì vậy để an toàn, dù sao nó cũng có thể tự tạo lại. Tôi đã xem mã nguồn cho ứng dụng Android Music và không thấy bất kỳ xử lý nút quay lại đặc biệt nào.
Mirko N.

46

Sử dụng mã sau đây:

public void onBackPressed() {    
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    startActivity(intent);
}

23

Nếu bạn muốn bắt nút Quay lại, hãy xem bài đăng này trên Blog của nhà phát triển Android . Nó bao gồm cách dễ dàng hơn để làm điều này trong Android 2.0 và cách tốt nhất để làm điều này cho một ứng dụng chạy trên 1.x và 2.0.

Tuy nhiên, nếu Hoạt động của bạn bị dừng, nó vẫn có thể bị tắt tùy thuộc vào bộ nhớ khả dụng trên thiết bị. Nếu bạn muốn một quy trình chạy mà không có UI, bạn nên tạo một Service. Tài liệu nói về các dịch vụ sau:

Một dịch vụ không có giao diện người dùng trực quan, mà chạy trong nền trong một khoảng thời gian không xác định. Ví dụ: một dịch vụ có thể phát nhạc nền khi người dùng liên quan đến các vấn đề khác hoặc có thể tìm nạp dữ liệu qua mạng hoặc tính toán một cái gì đó và cung cấp kết quả cho các hoạt động cần nó.

Chúng có vẻ phù hợp với yêu cầu của bạn.



14

nếu nó giúp được người khác, tôi đã có một hoạt động với 2 bố cục mà tôi bật và tắt cho thấy rõ, cố gắng mô phỏng một loại cấu trúc page1> page2. nếu họ ở trang 2 và nhấn nút quay lại, tôi muốn họ quay lại trang 1, nếu họ nhấn nút quay lại ở trang 1 thì nó vẫn hoạt động như bình thường. Nó khá cơ bản nhưng nó hoạt động

@Override
public void onBackPressed() {
// check if page 2 is open
    RelativeLayout page2layout = (RelativeLayout)findViewById(R.id.page2layout);
    if(page2layout.getVisibility() == View.VISIBLE){
        togglePageLayout(); // my method to toggle the views
        return;
    }else{
        super.onBackPressed(); // allows standard use of backbutton for page 1
    }

}

hy vọng nó sẽ giúp được ai đó


10

Ví dụ làm việc ..

Đảm bảo không gọi super.onBackPression ();

@Override
public void onBackPressed() {
   Log.d("CDA", "onBackPressed Called");
   Intent setIntent = new Intent(Intent.ACTION_MAIN);
   setIntent.addCategory(Intent.CATEGORY_HOME);
   setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(setIntent);
}

Theo cách này, Nút Quay lại của bạn hoạt động giống như nút Home. Nó không kết thúc hoạt động của bạn nhưng đưa nó vào nền

Cách thứ hai là gọi moveTaskToBack(true);vào onBackPressedvà chắc chắn xóasuper.onBackPressed


0

Thậm chí tốt hơn, làm thế nào về OnPause () :

Được gọi là một phần của vòng đời hoạt động khi một hoạt động đang đi vào nền, nhưng chưa (chưa) bị giết. Bản sao của onResume ().

Khi hoạt động B được khởi chạy trước hoạt động A, cuộc gọi lại này sẽ được gọi vào A. B sẽ không được tạo cho đến khi onPause () của A trở lại, vì vậy hãy chắc chắn enter code herekhông làm gì dài dòng ở đây.

Cuộc gọi lại này chủ yếu được sử dụng để lưu bất kỳ trạng thái liên tục nào mà hoạt động đang chỉnh sửa và đảm bảo không có gì bị mất nếu không có đủ tài nguyên để bắt đầu hoạt động mới mà không giết chết hoạt động này trước.

Đây cũng là một nơi tốt để thực hiện những việc như dừng hoạt hình và những thứ khác tiêu thụ một lượng CPU đáng chú ý để chuyển sang hoạt động tiếp theo nhanh nhất có thể hoặc đóng tài nguyên truy cập độc quyền như máy ảnh.


0

Ghi đè onBackPression () sau Android 2.0. Nhu la

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

0

Tôi đã thử tất cả các giải pháp trên, nhưng không có giải pháp nào phù hợp với tôi. Đoạn mã sau đã giúp tôi, khi cố gắng quay lại MainActivity theo cách mà onCreate được gọi:

Ý định.FLAG_ACTIVITY_CLEAR_TOP là khóa.

  @Override
  public void onBackPressed() {
      Intent intent = new Intent(this, MainActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivity(intent);
  }

-1

Tôi đã sử dụng @Mirko N. người trả lời bằng cách sử dụng Chỉnh sửa tùy chỉnh mới

 public class EditViewCustom extends EditText {

    Button cancelBtn;
    RelativeLayout titleReleLayout;
    public EditViewCustom(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public EditViewCustom(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditViewCustom(Context context) {
        super(context);
    }

    public void setViews(Button cancelBtn,RelativeLayout titleReleLayout){
        this.cancelBtn = cancelBtn;
        this.titleReleLayout = titleReleLayout;
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            Log.d("KEYCODE_BACK","KEYCODE_BACK");
            cancelBtn.setVisibility(View.GONE);
            this.setFocusableInTouchMode(false);
            this.setFocusable(false);
            titleReleLayout.setVisibility(View.VISIBLE);

            return super.onKeyPreIme(keyCode, event);
          }

        return super.onKeyPreIme(keyCode, event);
    }

}

Sau đó đặt dữ liệu từ hoạt động của bạn

 searchEditView.setViews(cancelBtn, titleRelativeLayout);

Cảm ơn bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.