blob: 83e7669a7f7676028c73e69744a67ca905a7e419 [file] [log] [blame]
page.title=Các hot động
page.tags=hot động định
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>Trong tài liu này</h2>
<ol>
<li><a href="#Creating">To mt Hot động</a>
<ol>
<li><a href="#UI">Trin khai mt giao din người dùng</a></li>
<li><a href="#Declaring">Khai báo hot động trong bn kê khai</a></li>
</ol>
</li>
<li><a href="#StartingAnActivity">Bt đầu mt Hot động</a>
<ol>
<li><a href="#StartingAnActivityForResult">Bt đầu mt hot động cho mt kết quả</a></li>
</ol>
</li>
<li><a href="#ShuttingDown">Tt mt Hot động</a></li>
<li><a href="#Lifecycle">Qun lý Vòng đời ca Hot động</a>
<ol>
<li><a href="#ImplementingLifecycleCallbacks">Trin khai gi li vòng đời</a></li>
<li><a href="#SavingActivityState">Lưu trng thái ca hot động</a></li>
<li><a href="#ConfigurationChanges">X lý thay đổi v cu hình</a></li>
<li><a href="#CoordinatingActivities"iu phi hot động</a></li>
</ol>
</li>
</ol>
<h2>Lp khóa</h2>
<ol>
<li>{@link android.app.Activity}</li>
</ol>
<h2>Xem thêm</h2>
<ol>
<li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tác v và Ngăn
Xếp</a></li>
</ol>
</div>
</div>
<p>{@link android.app.Activity} là mt thành phn ng dng cung cp mt màn hình mà vi nó
người dùng có th tương tác để thc hin mt điu gì đó, chng hn như quay s đin thoi, chp nh, gi e-mail hoc
xem bn đồ. Mi hot động được cho trong mt ca s là nơi để v giao din người dùng ca nó. Ca s này
thường lp đầy màn hình, nhưng có th nh hơn màn hình và ni bên trên các ca s
khác.</p>
<p> ng dng thường bao gm nhiu hot động được liên kết lng lo
vi nhau. Thường thì mt hot động trong mt ng dng s được quy định là hot động "chính", nó được
trình bày trước người dùng khi khi chy ng dng ln đầu. Sau đó, mi
hot động có th bt đầu mt hot động khác để thc hin các hành động khác nhau. Mi khi mt hot động
mi bt đầu, hot động trước đó s b dng li, nhưng h thng vn gi nguyên hot động
trong mt ngăn xếp ("back stack"). Khi mt hot động mi bt đầu, nó được đẩy lên ngăn xếp và
chiếm ly tiêu đim ca người dùng. Ngăn xếp s tuân theo cơ chế xếp chng cơ bn "vào cuối, ra đầu",
vì thế, khi người dùng kết thúc hot động hin ti và nhn nút <em>Quay li</em>, nó
s được đẩy ra khi ngăn xếp (và b hy) và hot động trước đó s tiếp tc. (Ngăn xếp được
đề cp k hơn trong tài liu <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tác v
và Ngăn Xếp</a>.)</p>
<p>Khi mt hot động b dng vì mt hot động mi bt đầu, nó được thông báo v s thay đổi trng thái này
qua các phương pháp gi li vòng đời ca hot động.
Có mt vài phương pháp gi li vòng đời mà mt hot động có th nhn, do mt thay đổi v
trng thái ca nó&mdash;dù h thng đang to, dng hay tiếp tc nó, hay hy nó&mdash;và
mi ln gi li cho bn cơ hi thc hin công vic c th
phù hp vi s thay đổi trng thái đó. Ví dụ, khi b dng, hot động ca bn s gii phóng mi
đối tượng ln, chng hn như các kết ni mng hoc cơ s d liu. Khi hot động tiếp tc, bn có th
thu li nhng tài nguyên cn thiết và tiếp tc nhng hành động b gián đon. Nhng chuyn tiếp trng thái này
đều là mt phn ca vòng đời hot động.</p>
<p>Phn còn li ca tài liu này bàn đến nhng ni dung cơ bn v cách xây dng và s dng mt hot động,
bao gm mt ni dung đề cp đầy đủ v cách vn hành ca vòng đời hot động, để bn có th qun lý tt
s chuyn tiếp gia các trng thái hot động khác nhau.</p>
<h2 id="Creating">To mt Hot động</h2>
<p>Để to mt hot động, bn phi to mt lp con ca {@link android.app.Activity} (hoc
mt lp con hin ti ca nó). Trong lp con ca mình, bn cn trin khai các phương pháp gi li mà h thng
gi khi hot động chuyn tiếp gia các trng thái khác nhau trong vòng đời, chng hn như khi
hot động đang được to, dng, tiếp tc, hoc hy. Hai phương pháp gi li quan trng nht
là:</p>
<dl>
<dt>{@link android.app.Activity#onCreate onCreate()}</dt>
<dd>Bn phi trin khai phương pháp này. H thng gi phương pháp này khi to hot động
ca bn. Trong quá trình thc hin ca mình, bn nên khi chy nhng thành phn thiết yếu cho hot động
ca mình.
Quan trng nht, đây là lúc bn phi gi {@link android.app.Activity#setContentView
setContentView()} để định nghĩa b trí cho giao din người dùng ca hot động.</dd>
<dt>{@link android.app.Activity#onPause onPause()}</dt>
<dd>H thng gi phương pháp này là du hiu đầu tiên v vic người dùng đang ri khi hot động
ca bn (mc dù không phi lúc nào cũng có nghĩa rng hot động đang b hy). Trường hp này thường là khi bn
định thc hin bt k thay đổi nào vn cn có hiu lc ngoài phiên ca người dùng hin thi (vì
người dùng có th không quay li).</dd>
</dl>
<p>Có mt vài phương pháp gi li vòng đời khác mà bn nên s dng để đem đến
mt tri nghim người dùng mượt mà gia các hot động và x lý nhng gián đon bt ng khiến hot động ca bn
b dng và thm chí b hy. Tt c phương pháp gi li vòng đời được bàn sau trong phn
nói v <a href="#Lifecycle">Qun lý Vòng đời ca Hot động</a>.</p>
<h3 id="UI">Trin khai mt giao din người dùng</h3>
<p> Giao din người dùng cho mt hot động s được cung cp theo phân cp dng xem&mdash;đối tượng được suy ra
t lp {@link android.view.View}. Mi chế độ xem kim soát mt không gian ch nht riêng
trong ca s ca hot động và có th phn hi trước tương tác ca người dùng. Ví dụ, chế độ xem có th là
mt nút khi xướng mt hành động khi người dùng chm vào nó.</p>
<p>Android cung cp nhiu chế độ xem sn có mà bn có th s dng để thiết kế và t chc cho b trí
ca mình. "Widget" là nhng chế độ xem cung cp nhng phn t trc quan (và tương tác) cho màn hình, chng hn như
nút, trường văn bn, hp kim, hay ch là mt hình nh. "Bố trí" là nhng chế độ xem được suy ra t {@link
android.view.ViewGroup} cung cp mt mô hình b trí duy nht cho các chế độ xem con ca nó, chng hn như b trí
tuyến tính, b trí lưới, hoc b trí tương đối. Bn cũng có th chia thành lp con {@link android.view.View} và các lp
{@link android.view.ViewGroup} (hoc các lp con hin ti) để to widget và
b trí ca chính mình và áp dng chúng vào b trí hot động ca bn.</p>
<p>Cách ph biến nht để định nghĩa mt b trí bng cách s dng các chế độ xem là dùng mt tp b trí XML được lưu trong tài nguyên ng dng
ca bn. Bng cách này, bn có th duy trì thiết kế giao din người dùng ca mình độc lp vi
mã ngun định nghĩa hành vi ca hot động. Bn có th đặt b trí làm UI cho hot động
ca mình bng {@link android.app.Activity#setContentView(int) setContentView()}, chuyển
ID tài nguyên cho b trí. Tuy nhiên, bn cũng có th to {@link android.view.View} mi trong mã hot động
ca mình và xây dng mt cp bc chế độ xem bng cách chèn các {@link
android.view.View} mi vào mt {@link android.view.ViewGroup}, sau đó s dng b trí đó bng cách chuyn root
{@link android.view.ViewGroup} sang {@link android.app.Activity#setContentView(View)
setContentView()}.</p>
<p>Để biết thông tin v vic to mt giao din người dùng, hãy xem tài liu <a href="{@docRoot}guide/topics/ui/index.html">Giao din Người dùng</a>.</p>
<h3 id="Declaring">Khai báo hot động trong bn kê khai</h3>
<p>Bn phi khai báo hot động ca mình trong tp bn kê khai để hot động
có th truy cp được vào h thng. Để khai báo hot động ca mình, hãy m tp bn kê khai ca bn và thêm mt phn t <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
làm con ca phn t <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
. Ví dụ:</p>
<pre>
&lt;manifest ... &gt;
&lt;application ... &gt;
&lt;activity android:name=".ExampleActivity" /&gt;
...
&lt;/application ... &gt;
...
&lt;/manifest &gt;
</pre>
<p>Có vài thuc tính khác mà bn có th nêu trong phn t này, để định nghĩa các thuc tính
như nhãn cho hot động, biu tượng cho hot động, hoc ch đề mô t kiu UI ca
hot động. Thuc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">{@code android:name}</a>
là thuc tính bt buc duy nht&mdash;nó quy định tên lp ca hot động. Mt khi
bn phát hành ng dng ca mình, bn không nên thay đổi tên này, vì nếu bn làm vy, bn có th làm hng
mt s tính năng, chng hn như các li tt ca ng dng (hãy đọc bài đăng trên blog, <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Nhng Điu
Không Thay Đổi Được</a>).</p>
<p>Xem tài liu tham kho phn t <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
để biết thêm thông tin v vic khai báo hot động ca bn trong bn kê khai.</p>
<h4>S dng các b lc ý định</h4>
<p>Mt phn t <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
&lt;activity&gt;}</a> cũng có thể quy định các bộ lọc ý định khác nhau&mdash;bằng cách sử dụng phần tử <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
&lt;intent-filter&gt;}</a> &mdash;để khai báo cách thức mà các thành phần khác của ứng dụng có thể
kích hoạt nó.</p>
<p>Khi bạn tạo một ứng dụng mới bằng cách sử dụng các công cụ SDK của Android, hoạt động chương trình nhỏ
được tạo cho bạn sẽ tự động bao gồm một bộ lọc ý định khai báo hoạt động
phản hồi lại hành động "chính" và nên được đặt trong thể loại "trình khi chy". Bộ lọc ý định
trông như thế này:</p>
<pre>
&lt;activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"&gt;
&lt;intent-filter&gt;
&lt;action android:name="android.intent.action.MAIN" /&gt;
&lt;category android:name="android.intent.category.LAUNCHER" /&gt;
&lt;/intent-filter&gt;
&lt;/activity&gt;
</pre>
<p>Phần tử <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
&lt;action&gt;}</a> quy định rằng đây là điểm mục nhập "chính" đối với ứng dụng. Phần tử <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
&lt;category&gt;}</a> quy định rằng hoạt động này nên được liệt kê trong trình khởi chạy ứng dụng của hệ thống
(để cho phép người dùng khởi chạy hoạt động này).</p>
<p>Nếu bạn có ý định cho ứng dụng của mình được độc lập và không cho phép các ứng dụng khác
kích hoạt các hoạt động của nó, vậy bạn không cần bất kỳ bộ lọc ý định nào khác. Chỉ một hoạt động nên có
hành động "chính" và thể loại "trình khi chy" như trong ví dụ trước. Những hoạt động mà
bạn không muốn cung cấp sẵn cho các ứng dụng khác không nên có bộ lọc ý định và bạn có thể
tự mình bắt đầu chúng bằng cách sử dụng các ý định rõ ràng (như được đề cập trong phần sau).</p>
<p>Tuy nhiên, nếu bạn muốn hoạt động của mình phản hồi lại những ý định ngầm mà được chuyển giao từ
các ứng dụng khác (và chính bạn), thì bạn phải định nghĩa các bộ lọc ý định bổ sung cho hoạt động
của mình. Với mỗi loại ý định mà bạn muốn phản hồi, bạn phải nêu một <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
&lt;intent-filter&gt;}</a> bao gồm một phần tử
<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
&lt;action&gt;}</a> và, không bắt buộc, một phần tử <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
&lt;category&gt;}</a> và/hoặc một phần tử <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
&lt;data&gt;}</a>. Những phần tử này quy định loại ý định mà hoạt động của bạn có thể
phản hồi.</p>
<p>Để biết thêm thông tin về cách thức các hoạt động của bạn có thể phản hồi lại ý định, hãy xem tài liệu <a href="{@docRoot}guide/components/intents-filters.html">Ý định và Bộ lọc Ý định</a>
.</p>
<h2 id="StartingAnActivity">Bắt đầu một Hoạt động</h2>
<p>Bạn có thể bắt đầu một hoạt động khác bằng cách gọi {@link android.app.Activity#startActivity
startActivity()}, chuyển cho nó một {@link android.content.Intent} mà mô tả hoạt động bạn
muốn bắt đầu. Ý định này sẽ quy định hoặc hoạt động chính xác mà bạn muốn bắt đầu hoặc mô tả
loại hành động mà bạn muốn thực hiện (và hệ thống lựa chọn hoạt động phù hợp cho bạn,
thậm chí
có thể từ một ứng dụng khác). Một ý định cũng có thể mang theo lượng nhỏ dữ liệu sẽ được
sử dụng bởi hoạt động được bắt đầu.</p>
<p>Khi đang làm việc trong ứng dụng của chính mình, bạn thường sẽ cần khởi chạy một hoạt động đã biết.
Bạn có thể làm vậy bằng cách tạo một ý định trong đó quy định rõ hoạt động bạn muốn bắt đầu,
sử dụng tên lớp đó. Ví dụ, sau đây là cách một hoạt động bắt đầu một hoạt động khác có tên {@code
SignInActivity}:</p>
<pre>
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
</pre>
<p>Tuy nhiên, ứng dụng của bạn cũng có thể muốn thực hiện một số hành động, chẳng hạn như gửi một e-mail, tin nhắn
văn bản, hoặc cập nhật trạng thái, bằng cách sử dụng dữ liệu từ hoạt động của bạn. Trong trường hợp này, ứng dụng của bạn có thể
không có các hoạt động của chính nó để thực hiện những hành động đó, vì vậy, thay vào đó, bạn có thể tận dụng những hoạt động
được cung cấp bởi các ứng dụng khác trên thiết bị mà có thể thực hiện hành động cho bạn. Đây là lúc
ý định thực sự có giá trị&mdash;bạn có thể tạo một ý định mô tả một hành động bạn muốn
thực hiện và hệ thống
sẽ khởi chạy hoạt động phù hợp đó từ một ứng dụng khác. Nếu có
nhiều hoạt động mà có thể xử lý ý định, vậy người dùng có thể chọn hoạt động nào sẽ sử dụng. Ví
dụ, nếu bạn muốn cho phép người dùng gửi e-mail, bạn có thể tạo
ý định sau:</p>
<pre>
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
</pre>
<p>{@link android.content.Intent#EXTRA_EMAIL} phụ được thêm vào ý định là một mảng xâu của
các địa chỉ e-mail mà e-mail sẽ được gửi tới. Khi một ứng dụng e-mail phản hồi
ý định này, nó đọc mảng xâu được cung cấp trong phần phụ và đặt nó vào trường "đến" của mẫu soạn thảo
e-mail. Trong trường hợp này, hoạt động của ứng dụng e-mail bắt đầu và khi người dùng
làm xong, hoạt động của bạn sẽ tiếp tục.</p>
<h3 id="StartingAnActivityForResult">Bắt đầu một hoạt động cho một kết quả</h3>
<p>Đôi khi bạn có thể muốn nhận được một kết quả từ hoạt động mà bạn bắt đầu. Trong trường hợp đó,
hãy bắt đầu hoạt động bằng cách gọi {@link android.app.Activity#startActivityForResult
startActivityForResult()} (thay vì {@link android.app.Activity#startActivity
startActivity()}). Rồi để nhận được kết quả từ hoạt động
sau đó, hãy triển khai phương pháp gọi lại {@link android.app.Activity#onActivityResult onActivityResult()}
. Khi hoạt động sau đó diễn ra xong, nó trả về một kết quả trong một {@link
android.content.Intent} cho phương pháp {@link android.app.Activity#onActivityResult onActivityResult()}
của bạn.</p>
<p>Ví dụ, bạn có thể muốn người dùng chọn một trong các liên lạc của họ, vì vậy hoạt động của bạn có thể
làm gì đó với thông tin trong liên lạc đó. Đây là cách bạn có thể tạo một ý định như vậy và
xử lý kết quả:</p>
<pre>
private void pickContact() {
// Create an intent to "pick" a contact, as defined by the content provider URI
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT_REQUEST);
}
&#64;Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// If the request went well (OK) and the request was PICK_CONTACT_REQUEST
if (resultCode == Activity.RESULT_OK &amp;&amp; requestCode == PICK_CONTACT_REQUEST) {
// Perform a query to the contact's content provider for the contact's name
Cursor cursor = getContentResolver().query(data.getData(),
new String[] {Contacts.DISPLAY_NAME}, null, null, null);
if (cursor.moveToFirst()) { // True if the cursor is not empty
int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
String name = cursor.getString(columnIndex);
// Do something with the selected contact's name...
}
}
}
</pre>
<p>Ví dụ này thể hiện lô-gic cơ bản mà bạn sẽ sử dụng trong phương pháp {@link
android.app.Activity#onActivityResult onActivityResult()} của mình để xử lý một
kết quả hoạt động. Điều kiện đầu tiên kiểm tra xem yêu cầu có thành công không&mdash;nếu có thì
{@code resultCode} sẽ là {@link android.app.Activity#RESULT_OK}&mdash;và liệu yêu cầu
mà kiểm tra này đang phản hồi có được biết hay không&mdash;trong trường hợp này, {@code requestCode} phù hợp với
tham số thứ hai được gửi bằng {@link android.app.Activity#startActivityForResult
startActivityForResult()}. Từ đó, mã xử lý kết quả hoạt động bằng cách truy vấn
dữ liệu được trả về trong {@link android.content.Intent} (tham số {@code data}).</p>
<p>Điều xảy ra đó là, {@link
android.content.ContentResolver} sẽ thực hiện một truy vấn đối với nhà cung cấp nội dung, truy vấn này trả về một
{@link android.database.Cursor} cho phép đọc dữ liệu được truy vấn. Để biết thêm thông tin, hãy xem tài liệu
<a href="{@docRoot}guide/topics/providers/content-providers.html">Trình cung cấp Nội dung</a>.</p>
<p>Để biết thêm thông tin về việc sử dụng ý định, hãy xem tài liệu <a href="{@docRoot}guide/components/intents-filters.html">Ý định và Bộ lọc
Ý định</a>.</p>
<h2 id="ShuttingDown">Tắt một Hoạt động</h2>
<p>Bạn có thể tắt một hoạt động bằng cách gọi phương pháp {@link android.app.Activity#finish
finish()} của nó. Bạn cũng có thể tắt một hoạt động riêng mà trước đó bạn đã bắt đầu bằng cách gọi
{@link android.app.Activity#finishActivity finishActivity()}.</p>
<p class="note"><strong>Lưu ý:</strong> Trong hầu hết trường hợp, bạn không nên kết thúc một hoạt động một cách rõ ràng
bằng cách sử dụng những phương pháp này. Như đề cập trong phần sau về vòng đời của hoạt động, hệ thống
Android quản lý tuổi thọ của một hoạt động cho bạn, vì vậy bạn không cần kết thúc các hoạt động
của chính mình. Việc gọi những phương pháp này có thể ảnh hưởng tiêu cực tới trải nghiệm người dùng
kỳ vọng và chỉ nên được sử dụng khi bạn tuyệt đối không muốn người dùng quay lại thực thể này của
hoạt động.</p>
<h2 id="Lifecycle">Quản lý Vòng đời của Hoạt động</h2>
<p>Việc quản lý vòng đời các hoạt động của bạn bằng cách triển khai các phương pháp gọi lại
rất quan trọng đối với việc xây dựng một ứng dụng mạnh
và linh hoạt. Vòng đời của một hoạt động trực tiếp bị ảnh hưởng bởi sự liên kết giữa nó với
các hoạt động khác, tác vụ của nó và ngăn xếp (back stack).</p>
<p>Về cơ bản, một hoạt động có thể tồn tại ở ba trạng thái:</p>
<dl>
<dt><i>Tiếp tục</i></dt>
<dd>Hoạt động ở tiền cảnh của màn hình và có tiêu điểm của người dùng. (Trạng thái này
đôi khi cũng được gọi là "đang chy".)</dd>
<dt><i>Tạm dừng</i></dt>
<dd>Một hoạt động khác ở tiền cảnh và có tiêu điểm, nhưng hoạt động này vẫn hiển thị. Cụ thể,
một hoạt động khác hiển thị ở trên hoạt động này và hoạt động đó trong suốt một phần hoặc không
che toàn bộ màn hình. Trạng thái tạm dừng hoàn toàn đang hoạt động (đối tượng {@link android.app.Activity}
được giữ lại trong bộ nhớ, nó duy trì tất cả thông tin về trạng thái và thành viên, và vẫn gắn với
trình quản lý cửa sổ), nhưng có thể bị hệ thống tắt bỏ trong trường hợp bộ nhớ cực kỳ thấp.</dd>
<dt><i>Dừng</i></dt>
<dd>Hoạt động bị che khuất hoàn toàn bởi một hoạt động khác (hoạt động hiện đang
“dưới nền"). Hot động dng cũng vn đang hot động ({@link android.app.Activity}
đối tượng được gi li trong bộ nhớ, nó duy trì tt c thông tin v trng thái và thành viên, nhưng <em>không</em>
gn vi trình qun lý ca sổ). Tuy nhiên, hot động không còn hin th vi người dùng na và h thng
có th tt b hot động này khi cn bộ nh nơi khác.</dd>
</dl>
<p>Nếu mt hot động b tm dng hoc dng, h thng có th b nó khi bộ nh hoc bng cách yêu cu nó
kết thúc (gi phương pháp {@link android.app.Activity#finish finish()} của nó), hoặc đơn giản là tắt bỏ tiến trình
ca hot động. Khi hot động được m li (sau khi b kết thúc hoc tt bỏ), nó phi được to
li hoàn toàn.</p>
<h3 id="ImplementingLifecycleCallbacks">Trin khai gi li vòng đời</h3>
<p>Khi mt hot động chuyn tiếp vào ra các trng thái khác nhau nêu trên, nó được thông báo
thông qua các phương pháp gi li. Tt c phương pháp gi li đều là nhng móc (hook) mà bn
có th khng chế để làm công vic phù hp khi trng thái hot động ca bn thay đổi. Hot động khung sau
bao gm tng phương pháp trong các phương pháp vòng đời cơ bn:</p>
<pre>
public class ExampleActivity extends Activity {
&#64;Override
public void {@link android.app.Activity#onCreate onCreate}(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
}
&#64;Override
protected void {@link android.app.Activity#onStart onStart()} {
super.onStart();
// The activity is about to become visible.
}
&#64;Override
protected void {@link android.app.Activity#onResume onResume()} {
super.onResume();
// The activity has become visible (it is now "resumed").
}
&#64;Override
protected void {@link android.app.Activity#onPause onPause()} {
super.onPause();
// Another activity is taking focus (this activity is about to be "paused").
}
&#64;Override
protected void {@link android.app.Activity#onStop onStop()} {
super.onStop();
// The activity is no longer visible (it is now "stopped")
}
&#64;Override
protected void {@link android.app.Activity#onDestroy onDestroy()} {
super.onDestroy();
// The activity is about to be destroyed.
}
}
</pre>
<p class="note"><strong>Lưu ý:</strong> Vic bn trin khai nhng phương pháp vòng đời này phi luôn
gi trin khai siêu lp trước khi làm bt k công vic nào, như minh ha trong các ví d bên trên.</p>
<p>Cùng nhau, nhng phương pháp này định nghĩa toàn b vòng đời ca mt hot động. Bng vic trin khai nhng phương pháp
này, bn có th theo dõi ba vòng lp lng nhau trong vòng đời ca hot động: </p>
<ul>
<li><b>Toàn b vòng đời</b> ca mt hot động s xy ra t thi đim lnh gi đến {@link
android.app.Activity#onCreate onCreate()} cho tới thời điểm lệnh gọi đến {@link
android.app.Activity#onDestroy}. Hoạt động của bạn nên thực hiện thiết lập
trng thái "chung" (chng hn như định nghĩa b trí) trong {@link android.app.Activity#onCreate onCreate()}, và
gii phóng tt c tài nguyên còn li trong {@link android.app.Activity#onDestroy}. Ví dụ, nếu hoạt động của bạn
có mt lung đang chy ngm để ti xung d liu t mng, nó có th to
lung đó trong {@link android.app.Activity#onCreate onCreate()} rồi dừng luồng trong {@link
android.app.Activity#onDestroy}.</li>
<li><p><b>Vòng đời hin thị</b> ca mt hot động xy ra t thi đim lnh gi đến {@link
android.app.Activity#onStart onStart()} cho tới lệnh gọi đến {@link
android.app.Activity#onStop onStop()}. Trong thời gian này, người dùng có thể thấy hoạt động
trên màn hình và tương tác vi nó. Ví dụ, {@link android.app.Activity#onStop onStop()} được gọi
khi mt hot động mi bt đầu và không còn hin th na. Gia hai phương pháp này, bn có th
duy trì các tài nguyên cn để cho người dùng thy hot động. Ví dụ, bn có th đăng ký mt
{@link android.content.BroadcastReceiver} trong {@link
android.app.Activity#onStart onStart()} để theo dõi các thay đổi tác động tới UI của mình, và bỏ đăng ký
nó trong {@link android.app.Activity#onStop onStop()} khi người dùng không còn thấy thứ bạn đang
hin th na. H thng có th gi {@link android.app.Activity#onStart onStart()} và {@link
android.app.Activity#onStop onStop()} nhiều lần trong suốt vòng đời của hoạt động, khi đó
hot động luân chuyn gia trng thái hin th và n vi người dùng.</p></li>
<li><p><b>Vòng đời tin cnh</b> ca mt hot động xy ra t thi đim lnh gi đến {@link
android.app.Activity#onResume onResume()} cho tới thời điểm lệnh gọi đến {@link android.app.Activity#onPause
onPause()}. Trong thi gian này, hot động s phía trước tt c hot động khác trên màn hình và có
tiêu đim đầu vào ca người dùng. Hot động có th thường xuyên chuyn tiếp vào và ra tin cnh&mdash;ví
dụ, {@link android.app.Activity#onPause onPause()} được gọi khi thiết bị vào trạng thái ngủ hoặc
khi mt hp thoi xut hin. Vì trng thái này có th chuyn tiếp thường xuyên, mã trong hai phương pháp này nên
tương đối nh để tránh chuyn tiếp chm khiến người dùng phi đợi.</p></li>
</ul>
<p>Hình 1 minh ha nhng vòng lp này và các đường dn mà mt hot động có th din ra gia các trng thái.
Hình ch nht đại din cho các phương pháp gi li bn có th trin khai để thc hin thao tác khi
hot động chuyn tiếp gia nhng trng thái này. <p>
<img src="{@docRoot}images/activity_lifecycle.png" alt="" />
<p class="img-caption"><strong>Hình 1.</strong> Vòng đời của hoạt động.</p>
<p>Nhng phương pháp gi li vòng đời này cũng được lit kê trong bng 1, trong đó mô t tng phương pháp
gi li mt cách chi tiết hơn và xác định tng phương pháp
trong vòng đời tng th ca hot động, bao gm vic h thng có th tt b hot động hay không sau khi
phương pháp gi li hoàn tt.</p>
<p class="table-caption"><strong>Bng 1.</strong> Tóm tt các phương pháp gi li
trong vòng đời ca hot động.</p>
<table border="2" width="85%" frame="hsides" rules="rows">
<colgroup align="left" span="3"></colgroup>
<colgroup align="left"></colgroup>
<colgroup align="center"></colgroup>
<colgroup align="center"></colgroup>
<thead>
<tr><th colspan="3">Phương pháp</th> <th>Mô tả</th> <th>Có th tt b sau?</th> <th>Tiếp theo</th></tr>
</thead>
<tbody>
<tr>
<td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td>
<td>Được gi khi hot động mi được to.
Đây là lúc bn nên thc hin tt c thiết lp c định thông thường ca mình &mdash;
to chế độ xem, kết ghép d liu vi danh sách, v.v. Phương pháp này được chuyn cho
mt đối tượng Gói cha trng thái trước đây ca hot động, nếu trng thái
đó được thu li (xem phn <a href="#actstate">Lưu Trng thái Hot động</a>,
đon sau).
<p>Luôn được theo sau bi {@code onStart()}.</p></td>
<td align="center">Không</td>
<td align="center">{@code onStart()}</td>
</tr>
<tr>
<td rowspan="5" style="border-left: none; border-right: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td colspan="2" align="left"><code>{@link android.app.Activity#onRestart
onRestart()}</code></td>
<td>Được gi sau khi hot động đã được dng, ngay trước khi hot động được
bt đầu li.
<p>Luôn được theo sau bi {@code onStart()}</p></td>
<td align="center">Không</td>
<td align="center">{@code onStart()}</td>
</tr>
<tr>
<td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td>
<td>Được gi ngay trước khi hot động hin th trước người dùng.
<p>Được theo sau bi {@code onResume()} nếu hot động vào
tin cnh, hoc {@code onStop()} nếu hot động b n.</p></td>
<td align="center">Không</td>
<td align="center">{@code onResume()} <br/>hoc<br/> {@code onStop()}</td>
</tr>
<tr>
<td rowspan="2" style="border-left: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td>
<td>Được gi ngay trước khi hot động bt đầu
tương tác vi người dùng. Ti đim này, hot động nm
trên cùng ca chng hot động, trong đó mc nhp ca người dùng s đến hot động này.
<p>Luôn được theo sau bi {@code onPause()}.</p></td>
<td align="center">Không</td>
<td align="center">{@code onPause()}</td>
</tr>
<tr>
<td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td>
<td>Được gi khi h thng sp bt đầu tiếp tc mt hot động
khác. Phương pháp này thường được s dng để thc hin các thay đổi chưa lưu cho
d liu liên tc, dng các hot nh và nhng vic khác mà có th tiêu tn công sut
CPU, v.v. Nó s thc hin rt nhanh, vì
hot động tiếp theo s không được tiếp tc ti khi nó tr li.
<p>Được theo sau hoc bi {@code onResume()} nếu hot động
tr li phía trước, hoc bi {@code onStop()} nếu nó
không hin th vi người dùng.</td>
<td align="center"><strong style="color:#800000">Có</strong></td>
<td align="center">{@code onResume()} <br/>hoc<br/> {@code onStop()}</td>
</tr>
<tr>
<td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td>
<td>Được gi khi hot động không còn hin th vi người dùng. Điu này
có th xy ra vì nó đang b hy, hoc vì mt hot động khác
ang tn ti hoc mi) đã được tiếp tc và đang che khut nó.
<p>Được theo sau hoc bi {@code onRestart()} nếu
hot động đang quay li để tương tác vi người dùng, hoc bi
{@code onDestroy()} nếu hot động này s đi mt.</p></td>
<td align="center"><strong style="color:#800000">Có</strong></td>
<td align="center">{@code onRestart()} <br/>hoc<br/> {@code onDestroy()}</td>
</tr>
<tr>
<td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy
onDestroy()}</code></td>
<td>Được gi trước khi hot động b hy. Đây là ln gi cui cùng
mà hot động s nhn được. Nên gi nó hoc vì
hot động đang kết thúc (ai đó đã gi <code>{@link android.app.Activity#finish
finish()}</code> trên nó), hoc vì h thng đang tm thi hy thc th này ca
hot động để tiết kim b nh trng. Bn có th phân bit
nhng nhng kch bn này bng phương pháp <code>{@link
android.app.Activity#isFinishing isFinishing()}</code>.</td>
<td align="center"><strong style="color:#800000">Có</strong></td>
<td align="center"><em>không có gì</em></td>
</tr>
</tbody>
</table>
<p>Ct ghi "Có thể tắt bỏ sau?" cho biết liu h thng có th
tt b tiến trình đang lưu tr hot động vào bt c lúc nào <em>sau khi phương pháp tr về</em>, mà không
thc hin mt dòng mã khác ca hot động hay không. Ba phương pháp được ghi là "có": ({@link
android.app.Activity#onPause
onPause()}, {@link android.app.Activity#onStop onStop()}, và {@link android.app.Activity#onDestroy
onDestroy()}). Vì {@link android.app.Activity#onPause onPause()} là phương pháp đầu tiên
trong ba phương pháp, sau khi hot động được to, {@link android.app.Activity#onPause onPause()} là
phương pháp cui cùng được bo đảm s được gi trước khi tiến trình <em>có thể</em> b tt bỏ&mdash;nếu
h thng phi khôi phc bộ nh trong mt tình hung khn cp, khi đó {@link
android.app.Activity#onStop onStop()} và {@link android.app.Activity#onDestroy onDestroy()} có thể
không được gi. Vì thế, bn nên s dng {@link android.app.Activity#onPause onPause()} để ghi
d liu c định quan trng (chng hn như nhng chnh sa ca người dùng) vào thiết b lưu trữ. Tuy nhiên, bn nên chn lc
thông tin nào phi được gi li trong {@link android.app.Activity#onPause onPause()}, vì bất kỳ
th tc chn nào trong phương pháp này cũng chn chuyn tiếp sang hot động kế tiếp và làm chm tri nghim
ca người dùng.</p>
<p> Nhng phương pháp được ghi "Không" trong ct <b>Có th tt bỏ</b> s bo v tiến trình đang lưu tr
hot động khi b tt b t thi đim chúng được gi. Vì thế, mt hot động có th tt b được
t thi đim {@link android.app.Activity#onPause onPause()} trở về tới thời điểm
{@link android.app.Activity#onResume onResume()} sẽ được gọi. Nó sẽ không thể lại tắt bỏ được tới khi
{@link android.app.Activity#onPause onPause()} lại được gọi và trả về. </p>
<p class="note"><strong>Lưu ý:</strong> Mt hot động mà không th "tắt bỏ được" v mt k thut bi
định nghĩa này trong bng 1 vn có th b h thng tt bỏ&mdash;nhưng điu đó ch xy ra trong
nhng hoàn cnh cc đoan khi không còn gii pháp nào khác. Thi đim mt hot động có th b tt b được
đề cp k hơn trong tài liu <a href="{@docRoot}guide/components/processes-and-threads.html">Tiến trình và
Lung</a>.</p>
<h3 id="SavingActivityState">Lưu trng thái ca hot động</h3>
<p>Phn gii thiu v <a href="#Lifecycle">Qun lý Vòng đời ca Hot động</a> có đề cp sơ qua
rng
khi mt hot động b tm dng hoc dng, trng thái ca hot động đó s được gi li. Điu này đúng vì
đối tượng {@link android.app.Activity} vn được gi trong bộ nh khi nó b tm dng hoc
dng&mdash;tt c thông tin v các thành viên và trng thái hin ti ca nó vn hot động. Vì thế, bt k thay đổi nào
mà người dùng đã thc hin trong hot động đều được gi li sao cho khi hot động tr v
tin cnh (khi nó "tiếp tục"), thì nhng thay đổi này vn còn đó.</p>
<p>Tuy nhiên, khi h thng hy mt hot động để khôi phc bộ nhớ, đối tượng {@link
android.app.Activity} b hy, vì vy h thng không th đơn thun tiếp tc hot động vi trng thái
không b nh hưởng. Thay vào đó, h thng phi to li đối tượng {@link android.app.Activity} nếu người dùng
điu hướng tr li nó. Tuy vy, người dùng không biết
rng h thng đã hy hot động và to li nó và, vì thế, có th
cho rng hot động s vn nguyên như cũ. Trong tình hung này, bn có th đảm bo rng
thông tin quan trng v trng thái ca hot động được gi nguyên bng cách trin khai mt phương pháp gi li
b sung cho phép bn lưu thông tin v trng thái ca hot động ca mình: {@link
android.app.Activity#onSaveInstanceState onSaveInstanceState()}.</p>
<p>H thng gi {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}
trước khi khiến hot động d b hy. H thng chuyn cho phương pháp này
mt {@link android.os.Bundle} trong đó bn có th lưu
thông tin trng thái v hot động như cp tên giá trị, bng cách s dng các phương pháp như {@link
android.os.Bundle#putString putString()} và {@link
android.os.Bundle#putInt putInt()}. Sau đó, nếu hệ thống tắt bỏ tiến trình ứng dụng của bạn
và người dùng điu hướng tr li hot động ca bn, h thng s to li hot động đó và
chuyn {@link android.os.Bundle} cho c {@link android.app.Activity#onCreate onCreate()} và {@link
android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}. Sử dụng một trong
hai phương pháp này, bn có th trích xut trng thái đã lưu ca mình t {@link android.os.Bundle} và khôi phc
trng thái ca hot động. Nếu không có thông tin trng thái để khôi phc, khi đó {@link
android.os.Bundle} được chuyn cho bn s rng (là trường hp khi hot động được to
ln đầu).</p>
<img src="{@docRoot}images/fundamentals/restore_instance.png" alt="" />
<p class="img-caption"><strong>Hình 2.</strong> Hai cách mà theo đó mt hot động tr v tiêu đim
ca người dùng vi trng thái không thay đổi: hoc hot động b hy, ri to li và hot động phi khôi phc
trng thái đã lưu trước đó, hoc hot động b dng, ri tiếp tc và trng thái ca hot động
gi nguyên không đổi.</p>
<p class="note"><strong>Lưu ý:</strong> Không có gì bo đảm rng {@link
android.app.Activity#onSaveInstanceState onSaveInstanceState()} sẽ được gọi trước khi hoạt động
ca bn b hy, vì có nhng trường hp mà s không cn lưu trng thái
(chng hn như khi người dùng ri b hot động ca bn bng cách s dng nút <em>Quay li</em>, vì người dùng
rõ ràng
đang đóng hot động). Nếu h thng gi {@link android.app.Activity#onSaveInstanceState
onSaveInstanceState()}, nó làm vy trước {@link
android.app.Activity#onStop onStop()} và có thể trước cả {@link android.app.Activity#onPause
onPause()}.</p>
<p>Tuy nhiên, ngay c khi bn không làm gì và không trin khai {@link
android.app.Activity#onSaveInstanceState onSaveInstanceState()}, một phần trạng thái của hoạt động được khôi phục
bi vic lp {@link android.app.Activity} trin khai mc định {@link
android.app.Activity#onSaveInstanceState onSaveInstanceState()}. Cụ thể, triển khai
mc định s gi phương pháp {@link
android.view.View#onSaveInstanceState onSaveInstanceState()} tương ứng cho mọi {@link
android.view.View} trong b trí, nó cho phép mi chế độ xem cung cp thông tin v chính nó
mà s được lưu. Gn như mi widget trong khuôn kh Android đều trin khai phương pháp này nếu
phù hp, sao cho mi thay đổi hin th đối vi UI đều t động được lưu và khôi phc khi hot động
ca bn được to li. Ví dụ, widget {@link android.widget.EditText} lưu mi văn bn
do người dùng đin vào và widget {@link android.widget.CheckBox} lưu s thông tin cho dù đã được kim tra
hay chưa. Vic duy nht bn cn làm đó là cung cp mt ID duy nht (vi thuc tính <a href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a>
) cho mi widget bn mun lưu trng thái ca nó. Nếu mt widget không có ID thì h thng
không th lưu trng thái ca nó.</p>
<div class="sidebox-wrapper">
<div class="sidebox">
<p>Bn cũng có th rõ ràng dng mt chế độ xem trong b trí ca mình khi vic lưu trng thái ca nó bng cách đặt thuc tính
{@link android.R.attr#saveEnabled android:saveEnabled} thành {@code "false"} hoặc bằng cách gọi
phương pháp {@link android.view.View#setSaveEnabled setSaveEnabled()}. Thường thì bạn không nên
vô hiu hóa điu này, nhưng có th làm nếu bn mun khôi phc trng thái ca UI hot động khác đi.</p>
</div>
</div>
<p>Mc dù vic trin khai mc định {@link
android.app.Activity#onSaveInstanceState onSaveInstanceState()} lưu thông tin hữu ích về
UI hot động ca bn, bn có th vn cn khng chế nó để lưu thêm thông tin.
Ví dụ, bn có th cn lưu các giá tr thành viên đã thay đổi trong vòng đời ca hot động (mà
có th tương quan vi các giá tr được khôi phc trong UI, nhưng các thành viên nm gi giá tr UI đó không được
khôi phc theo mc định).</p>
<p>Vì vic trin khai mc định {@link
android.app.Activity#onSaveInstanceState onSaveInstanceState()} giúp lưu trạng thái của UI, nếu
bn khng chế phương pháp để lưu thêm thông tin trng thái, bn nên luôn luôn gi
trin khai siêu lp ca {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}
trước khi thc hin bt k công vic nào. Tương tự, bn cũng nên gi trin khai siêu lp {@link
android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} nếu bạn khống chế nó, để
trin khai mc định có th khôi phc các trng thái xem.</p>
<p class="note"><strong>Lưu ý:</strong> Vì {@link android.app.Activity#onSaveInstanceState
onSaveInstanceState()} không đảm bo
s được gi, bn ch nên s dng nó để ghi trng thái giao thi ca hot động (trng thái ca
UI)&mdash;bn không nên s dng nó để lưu gi d liu liên tc. Thay vào đó, bn nên s dng {@link
android.app.Activity#onPause onPause()} để lưu giữ dữ liệu liên tục (chẳng hạn như dữ liệu mà nên được lưu
vào mt cơ s d liu) khi người dùng ri b hot động.</p>
<p>Mt cách hay để kim tra kh năng khôi phc trng thái ca ng dng ca bn đó là ch cn xoay
thiết b sao cho hướng màn hình thay đổi. Khi hướng màn hình thay đổi, h thng
hy và to li hot động để áp dng các tài nguyên thay thế mà có th có sn
cho cu hình màn hình mi. Ch vi lý do này mà mt điu rt quan trng đó là hot động ca bn
hoàn toàn khôi phc trng thái ca mình khi nó được to li, vì người dùng thường xoay màn hình trong khi
s dng ng dng.</p>
<h3 id="ConfigurationChanges">X lý thay đổi v cu hình</h3>
<p>Mt s cu hình thiết b có th thay đổi trong thi gian chy (chng hn như hướng màn hình, s sn có
ca bàn phím, và ngôn ngữ). Khi s thay đổi đó din ra, Android to li hot động đang chy
(h thng gi {@link android.app.Activity#onDestroy}, rồi ngay lập tức gọi {@link
android.app.Activity#onCreate onCreate()}). Hành vi này
được thiết kế để giúp ng dng ca bn điu chnh theo nhng cu hình mi bng cách t động ti li ng dng
ca bn bng các tài nguyên thay thế mà bn đã cung cp (chng hn như b trí khác cho
các hướng và kích c màn hình khác).</p>
<p>Nếu bn thiết kế hot động ca mình mt cách phù hp để x lý khi động li do thay đổi hướng màn hình và
khôi phc trng thái hot động như nêu trên, ng dng ca bn s linh hot hơn trước
nhng s kin bt ng khác trong vòng đời ca hot động.</p>
<p>Cách tt nht để x lý khi động li đó là
lưu và khôi phc trng thái hot động ca bn bng cách s dng {@link
android.app.Activity#onSaveInstanceState onSaveInstanceState()} và {@link
android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} (hoặc {@link
android.app.Activity#onCreate onCreate()}), như đã đề cập trong phần trước.</p>
<p>Để biết thêm thông tin v nhng thay đổi cu hình xy ra ti thi đim chy và cách bn có th x lý
chúng, hãy đọc hướng dn <a href="{@docRoot}guide/topics/resources/runtime-changes.html">X lý
Thay đổi trong Thi gian chy</a>.</p>
<h3 id="CoordinatingActivities"iu phi hot động</h3>
<p>Khi mt hot động bt đầu mt hot động khác, c hai đều tri qua nhng chuyn tiếp vòng đời. Hot động th nht
tm dng và dng (tuy nhiên, nó s không dng nếu vn hin th được dưới nn), trong khi hot động kia
được to. Trong trường hp nhng hot động này chia s d liu được lưu vào đĩa hoc nơi khác, điu quan trng là
phi hiu rng hot động th nht không b dng hoàn toàn trước khi hot động th hai được to.
Thay vào đó, tiến trình bt đầu hot động th hai chng lp vi tiến trình dng hot động
th nht.</p>
<p>Th t gi li vòng đời được định nghĩa rõ, c th là khi hai hot động trong cùng tiến trình
và hot động này bt đầu hot động kia. Sau đây là th t thao tác din ra khi Hot động
A bt đầu Hot động B: </p>
<ol>
<li>Phương pháp {@link android.app.Activity#onPause onPause()} của Hoạt động A thực thi.</li>
<li>{@link android.app.Activity#onCreate onCreate()} của Hoạt động B, {@link
android.app.Activity#onStart onStart()}, và các phương pháp {@link android.app.Activity#onResume onResume()}
thc thi theo trình tự. (Hot động B lúc này có tiêu đim ca người dùng.)</li>
<li>Sau đó, nếu Hot động A không còn hin th trên màn hình, phương pháp {@link
android.app.Activity#onStop onStop()} của nó sẽ thực thi.</li>
</ol>
<p>Trình t gi li vòng đời có th d đoán này cho phép bn qun lý chuyn tiếp
thông tin t hot động này sang hot động khác. Ví dụ, nếu bn phi ghi vào mt cơ s d liu khi
hot động th nht dng sao cho hot động theo sau có th đọc nó, khi đó bn nên ghi vào
cơ s d liu trong khi {@link android.app.Activity#onPause onPause()} thay vì trong khi {@link
android.app.Activity#onStop onStop()}.</p>
<!--
<h2>Beginner's Path</h2>
<p>For more information about how Android maintains a history of activities and
enables user multitasking, continue with the <b><a
href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back
Stack</a></b> document.</p>
-->