Hoạt động tải lại trong Android


220

Có phải là một thực hành tốt để tải lại Activitytrong Android ?

Điều gì sẽ là cách tốt nhất để làm điều đó? this.finishvà sau đó this.startActivityvới các hoạt động Intent?


3
Tôi không phải là nhà phát triển Android có kinh nghiệm, nhưng khởi động lại một Activity có vẻ như thiết kế kém và chỉ nên được thực hiện trong những trường hợp cực đoan.
Hudson

@Hudson Đó là những gì xảy ra trên thay đổi cấu hình. Nếu đó là thiết kế tốt hay không, đó là một cuộc thảo luận hoàn toàn khác. ;)
hpique

1
@Hudson Vậy là bạn đã có 5 năm kinh nghiệm phát triển: D
Pratik Butani

@PratikButani, tôi có biết bạn không? :) Tôi có 8 năm kinh nghiệm bây giờ, nhưng không có nhiều trong quá trình phát triển Android.
Hudson

Bạn đã truy cập hồ sơ của tôi, tôi biết: P @Hudson
Pratik Butani

Câu trả lời:


521

Bạn chỉ có thể sử dụng

finish();
startActivity(getIntent());

để làm mới một Activitytừ bên trong chính nó.


2
Điều gì xảy ra nếu nó không thể được gọi trong lớp hoạt động?, Cách nào để thực hiện với tham chiếu ngữ cảnh?
giorgiline

1
@giorgiline - Có, tạo một giao diện mà bạn xác định bên trong lớp hoạt động và chuyển giao diện đó làm tham số cho bất kỳ lớp bên ngoài nào bạn đang sử dụng.
tổng

1
Wow, tôi đã không nghĩ rằng nó sẽ dễ dàng như vậy.
theblang

1
Làm thế nào bạn có thể đối phó với một hoạt động đã được bắt đầu cho kết quả? Bạn có thể khởi động lại với người gọi ban đầu vẫn nhận được kết quả không?
tothphu

1
@tothphu - Mặc dù chưa thử, nhưng về mặt lý thuyết tôi nghĩ là có. Tuy nhiên, lần thứ hai hoạt động kết thúc, nó sẽ không trả lại kết quả cho Hoạt động được tạo lần đầu tiên.
Sush

64

đối với những người không muốn thấy nháy mắt đó sau khi phương thức rece () chỉ cần sử dụng

 finish();
 overridePendingTransition(0, 0);
 startActivity(getIntent());
 overridePendingTransition(0, 0);

2
Tuyệt vời! Tôi muốn ghi đè Chuyển đổi để người dùng không chú ý!
Ceddy Muhoza

Bạn đã làm rất tốt! Người dùng sẽ hầu như không nhận thấy tải lại.
sam

38

Đây là những gì tôi làm để tải lại hoạt động sau khi thay đổi trở về từ thay đổi tùy chọn.

@Override
protected void onResume() {

   super.onResume();
   this.onCreate(null);
}

Điều này về cơ bản gây ra các hoạt động để vẽ lại chính nó.

Cập nhật: Một cách tốt hơn để làm điều này là gọi recreate()phương thức. Điều này sẽ khiến hoạt động được tạo lại.


15
Điều đó có thể đang hoạt động nhưng không nên gọi các phương thức vòng đời một cách rõ ràng.
ITisha

Nếu bạn đi theo tuyến đường này, bạn nên sử dụng một phương thức init () riêng biệt để thiết lập mọi thứ và gọi nó từ bên trong onCreate () và onResume (), thay vì gọi onCreate ().
Tom

1
Giải pháp tuyệt vời, ngoại trừ sẽ không hoạt động trong một số trường hợp khi phương pháp vòng đời của bạn được sử dụng cho những thứ khác. Chẳng hạn, tôi đang truy cập vào camera của điện thoại và khi ảnh được chụp, màn hình sẽ quay trở lại hoạt động của tôi để đăng nó lên chế độ xem. Bằng cách sử dụng các phương pháp vòng đời để làm mới, tôi bị loại khỏi quy trình máy ảnh và ảnh của tôi không quay trở lại hoạt động mà thay vào đó tôi có được hoạt động từ đầu. Chỉ là một ví dụ để nhận thức được.
Azurespot

1
Điều quan trọng là phải xem xét launchMode của hoạt động khi sử dụng tái tạo (). Ví dụ: khi tôi gọi tái tạo () trên một hoạt động với launchMode = singleTop, tôi không thấy onCreate () được gọi sau đó. OTOH, nếu, thay vì gọi tái tạo (), tôi gọi rõ kết thúc () và theo sau là startActivity (), tôi thấy onCreate () được gọi sau đó.
albert c braun

14

Tôi đã thấy các câu trả lời trước đó đã được đưa ra để tải lại hoạt động bằng Intent. Chúng sẽ hoạt động nhưng bạn cũng có thể thực hiện tương tự bằng cách sử dụng phương thức tái tạo () được đưa ra trong chính lớp Activity.

Thay vì viết cái này

// Làm mới hoạt động chính khi đóng hộp thoại

Intent refresh = new Intent(this, clsMainUIActivity.class);
startActivity(refresh);
this.finish();

Điều này có thể được thực hiện bằng cách chỉ viết

recreate();

recreate()là giải pháp cho tôi - "khởi động lại" hoạt động không hiệu quả với tôi, khi tôi bắt đầu hoạt động bằng cách sử dụng "StartActivityForResult" và nó đã phá vỡ hành vi.
KYL3R

13

chỉ cần sử dụng

this.recreate();

điều này sẽ kích hoạt phương thức onCreate trong hoạt động


10

Tôi cần cập nhật danh sách tin nhắn trong một trong các ứng dụng của mình một cách vội vàng, vì vậy tôi chỉ thực hiện làm mới hoạt động UI chính của mình trước khi đóng hộp thoại tôi đang ở. Tôi chắc chắn có nhiều cách tốt hơn để thực hiện điều này.

// Refresh main activity upon close of dialog box
Intent refresh = new Intent(this, clsMainUIActivity.class);
startActivity(refresh);
this.finish(); //

9

Android bao gồm một hệ thống quản lý quy trình xử lý việc tạo và hủy các hoạt động mà phần lớn phủ nhận bất kỳ lợi ích nào bạn thấy từ việc khởi động lại một hoạt động theo cách thủ công. Bạn có thể xem thêm thông tin về nó tại Ứng dụng cơ bản

Thực tế tốt là gì để đảm bảo rằng các phương thức onPause và onStop của bạn giải phóng mọi tài nguyên mà bạn không cần phải giữ và sử dụng onLowMemory để giảm các hoạt động cần thiết đến mức tối thiểu.


2
+1 để đề cập đến onLowMemory. Tôi không biết rằng phương pháp đó đã tồn tại!
hpique

4

Bắt đầu với một ý định của bạn giống nhau activityvà đóng activity.

Intent refresh = new Intent(this, Main.class);
startActivity(refresh);//Start the same Activity
finish(); //finish Activity.

4

trong một số trường hợp, đó là cách thực hành tốt nhất trong các trường hợp khác, đó không phải là ý tưởng hay nếu điều đó được định hướng theo bối cảnh nếu bạn chọn làm như vậy bằng cách sử dụng sau đây là cách tốt nhất để truyền từ một hoạt động cho con trai của cô ấy:

    Intent i = new Intent(myCurrentActivityName.this,activityIWishToRun.class);    
    startActivityForResult(i, GlobalDataStore.STATIC_INTEGER_VALUE);

điều này là bất cứ khi nào bạn kết thúc () từ hoạt độngIWishToRun bạn trở lại hoạt động sống của mình


1
Điều này có thể cũ nhưng bạn chỉ tiết kiệm cho tôi rất nhiều thời gian! :)
Lior Iluz

4

Tải lại toàn bộ hoạt động của bạn có thể là một nhiệm vụ nặng nề. Chỉ cần đặt một phần của mã phải được làm mới trong ( kotlin ):

override fun onResume() {
    super.onResume()
    //here...
}

Java:

@Override
public void onResume(){
    super.onResume();
    //here...

}

Và gọi " onResume () " bất cứ khi nào cần.


2

Tôi không nghĩ rằng đó là một ý tưởng tốt ... sẽ tốt hơn nếu thực hiện một phương pháp sạch hơn. Chẳng hạn, nếu hoạt động của bạn giữ một biểu mẫu, phương thức dọn dẹp chỉ có thể xóa từng tiện ích trong biểu mẫu và xóa tất cả dữ liệu tạm thời. Tôi đoán đó là những gì bạn muốn: khôi phục hoạt động về trạng thái ban đầu.


Trên thực tế, tôi muốn thay đổi trạng thái ứng dụng và sau đó tải lại hoạt động để phản ánh sự thay đổi.
hpique

"Trạng thái ứng dụng" trong trường hợp của bạn là gì? Sở thích?
zehrer

2

Sau khi thử nghiệm điều này một thời gian, tôi thấy không có hậu quả bất ngờ nào khi khởi động lại một hoạt động. Ngoài ra, tôi tin rằng điều này rất giống với những gì Android làm theo mặc định khi định hướng thay đổi, vì vậy tôi không thấy lý do để không làm điều đó trong một trường hợp tương tự.


Ngược lại, tôi đã cố gắng "làm mới" màn hình của mình bằng cách khởi động lại hoạt động. Nó không xuất hiện trên bề mặt bất cứ điều gì sai, thông tin của tôi đã cập nhật cách tôi muốn, LogCat kể một câu chuyện khác. Trong LogCat, tôi quay lại phương thức onCreate của hoạt động, nó cố gắng kéo các tùy chọn. Lần thử đầu tiên tôi nhận được một ngoại lệ con trỏ null, sau đó nó sẽ thử lại để bắt đầu trong onCreate và nhận được lưu trữPref lần thứ hai. Không chắc chắn những gì đang xảy ra ở đây, nhưng tôi chỉ muốn chắc chắn rằng bạn không chỉ đơn giản là nhìn vào kết quả, vì WYSIWIG không phải là trường hợp của tôi.
taraloca

Làm thế nào chính xác là bạn đang khởi động lại hoạt động?
hpique

2

tôi có cùng một vấn đề

import android.support.v4.content.IntentCompat;

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

mã này làm việc cho tôi. Api 17


2

Trong một hoạt động, bạn có thể gọi recreate()để "tạo lại" hoạt động (API 11+)


1

Tôi đã có một cách tiếp cận khác như: thiết lập launchModehoạt động của mình thành singleTopvà không gọi finish(), chỉ cần startActivity(getIntent())thực hiện công việc. Chỉ cần quan tâm đến dữ liệu mới cả trong onCreate()onNewIntent . Theo cách của Sush, ứng dụng có thể nhấp nháy như AMAN SINGH đã nói. Nhưng cách tiếp cận của AMAN SINGH vẫn sẽ tạo ra một hoạt động mới, bằng cách nào đó, không cần thiết, ngay cả khi anh ấy đã khắc phục vấn đề 'nháy mắt', tôi nghĩ vậy.

Quá muộn cho câu hỏi này, nhưng nếu ai đó đang tìm kiếm một giải pháp, thì đây là.


0

Sau khi đăng nhập tôi gặp vấn đề tương tự nên tôi đã sử dụng

@Override
protected void onRestart() {
    this.recreate();
    super.onRestart();
}


0

Đối với tôi, nó hoạt động không phải là tạo ra một Ý định khác và trên cùng một ý định mới được tải dữ liệu.

    overridePendingTransition(0, 0);
    finish();
    overridePendingTransition(0, 0);
    startActivity(getIntent());
    overridePendingTransition(0, 0);
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.