blob: 39e1c15b7a8bc99fb8b616f024e933c8ad916022 [file] [log] [blame]
page.title=Ti ưu hóa Chy ngm
page.metaDescription=Các hn chế mi đối vi truyn phát không biu thị.
page.keywords="android N", "implicit broadcasts", "job scheduler"
page.image=images/cards/card-nyc_2x.jpg
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>
Trong tài liu này
</h2>
<ol>
<li>
<a href="#connectivity-action">Các hn chế v CONNECTIVITY_ACTION</a>
</li>
<li>
<a href="#sched-jobs">Lên lch Tác v Mng trên Kết ni
Không đo lưu lượng</a>
</li>
<li>
<a href="#monitor-conn">Theo dõi Kết ni Mng Trong khi ng dng
đang Chy</a>
</li>
<li>
<a href="#media-broadcasts">Các hn chế v NEW_PICTURE và
NEW_VIDEO</a>
</li>
<li>
<a href="#new-jobinfo">Các phương thc JobInfo Mi</a>
</li>
<li>
<a href="#new-jobparam">Các phương thc JobParameter Mi</a>
</li>
<li>
<a href="#further-optimization">Ti ưu hóa thêm ng dng ca bn</a>
</li>
</ol>
</div>
</div>
<p>
Các tiến trình chy ngm có th tiêu tn b nh và pin. Ví dụ, mt
truyn phát không biu th có th bt đầu nhiu tiến trình chy ngm đã đăng ký
để theo dõi chúng, ngay c khi các tiến trình đó có th không làm vic nhiu. Điu này có th có
nh hưởng ln đến c hiu sut ca thiết b ln tri nghim ca người dùng.
</p>
<p>
Để loi b vn đề này, N Developer Preview áp dng các hn chế
sau:
</p>
<ul>
<li>Các ng dng nhm đến Preview không nhn được truyn phát {@link
android.net.ConnectivityManager#CONNECTIVITY_ACTION} nếu chúng
đăng ký nhn truyn phát trong bn kê khai ca chúng. Các ng dng đang chy tin cnh
vn có th theo dõi {@code CONNECTIVITY_CHANGE} trên lung chính ca chúng bng cách
đăng ký{@link android.content.BroadcastReceiver} vi {@link
android.content.Context#registerReceiver Context.registerReceiver()}.
</li>
<li>ng dng không th gi hoc nhn các truyn phát {@link
android.hardware.Camera#ACTION_NEW_PICTURE} hoặc {@link
android.hardware.Camera#ACTION_NEW_VIDEO}. Việc tối ưu này
tác động đến mi ng dng, không ch các ng dng nhm đến Preview.
</li>
</ul>
<p>
Khuôn kh Android cung cp mt s gii pháp để gim thiu s cn thiết đối vi
các truyn phát không biu thị. Ví dụ, {@link android.app.job.JobScheduler}
và <a href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
{@code GcmNetworkManager}</a> cung cp mt cơ chế lên lch hiu qu
cho các hot động mng khi đáp ng các điu kin được ch định, ví d như kết ni ti mng
không đo lưu lượng. Bây gi bn cũng có th s dng {@link android.app.job.JobScheduler}
để phn ng li vi các thay đổi đối vi các trình cung cp ni dung. Các đối tượng {@link android.app.job.JobInfo}
gói gn các tham s {@link android.app.job.JobScheduler}
dùng để lên lch tác v ca bn. Khi đáp ng được các điu kin ca tác vụ, h thng
s thc thi tác v này trên {@link android.app.job.JobService} ca ng dng ca bn.
</p>
<p>
Trong tài liu này, chúng ta s tìm hiu cách s dng các phương thc thay thế, chng hn như
{@link android.app.job.JobScheduler}, để thích ng ng dng ca bn vi các hn chế
mi này.
</p>
<h2 id="connectivity-action">
Các hn chế v CONNECTIVITY_ACTION
</h2>
<p>
Các ng dng nhm đến N Developer Preview không nhn được truyn phát {@link
android.net.ConnectivityManager#CONNECTIVITY_ACTION} nếu chúng
đăng ký nhn truyn phát trong bn kê khai ca chúng, và các tiến trình ph thuc vào truyn phát này
s không khi động. Điu này cũng đặt ra mt vn đề cho ng dng
v vic theo dõi thay đổi mng hoc thc hin các hot động mng hàng lot khi
thiết b kết ni vi mt mng không đo lưu lượng. Mt s gii pháp để tránh khi hn chế này
đã tn ti trong khuôn kh Android, nhưng chn được mt gii pháp phù hp
ph thuc vào nhng gì bn mun ng dng ca bn hoàn thành.
</p>
<p class="note">
<strong>Lưu ý:</strong> Mt{@link android.content.BroadcastReceiver} có đăng ký
{@link android.content.Context#registerReceiver Context.registerReceiver()}
tiếp tc nhn các truyn phát này trong khi ng dng đang tin cnh.
</p>
<h3 id="sched-jobs">
Lên lch Tác v Mng trên Kết ni Không đo lưu lượng
</h3>
<p>
Khi s dng lp{@link android.app.job.JobInfo.Builder JobInfo.Builder}
để xây dng đối tượng {@link android.app.job.JobInfo} ca bn, hãy áp dng phương thc {@link
android.app.job.JobInfo.Builder#setRequiredNetworkType
setRequiredNetworkType()} và chuyn {@link android.app.job.JobInfo
JobInfo.NETWORK_TYPE_UNMETERED} dưới dng mt tham s tác vụ. Đon mã mu sau
lên lch mt dch v để chy khi thiết b kết ni vi mt mng
không đo lưu lượng và đang sc:
</p>
<pre>
public static final int MY_BACKGROUND_JOB = 0;
...
public static void scheduleJob(Context context) {
JobScheduler js =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo job = new JobInfo.Builder(
MY_BACKGROUND_JOB,
new ComponentName(context, MyJobService.class))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresCharging(true)
.build();
js.schedule(job);
}
</pre>
<p>
Khi các điu kin cho tác v ca bn đã được đáp ng, ng dng ca bn s nhn được lnh gi li để chy
phương thc{@link android.app.job.JobService#onStartJob onStartJob()}trong
{@code JobService.class} được ch định. Để xem thêm các ví d v trin khai {@link
android.app.job.JobScheduler} , hãy xem <a href="{@docRoot}samples/JobScheduler/index.html">ứng dng mu JobScheduler</a>.
</p>
<p>
Các ng dng s dng dch v GMSCore, và nhm đến Android 5.0 (API mc 21)
hoc thp hơn, có th s dng <a href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager">
{@code GcmNetworkManager}</a> và quy định {@code Task.NETWORK_STATE_UNMETERED}.
</p>
<h3 id="monitor-conn">
Theo dõi Kết ni Mng Trong khi ng dng đang Chy
</h3>
<p>
Các ng dng đang chy tin cnh vn có th theo dõi {@code
CONNECTIVITY_CHANGE} bng mt{@link
android.content.BroadcastReceiver} đã đăng ký. Tuy nhiên, API {@link
android.net.ConnectivityManager} cung cp phương thc yêu cu lnh gi li hiu qu hơn
ch khi đáp ng được các điu kin được ch định.
</p>
<p>
Các đối tượng {@link android.net.NetworkRequest} định nghĩa các tham s ca
lnh gi li mng xét v {@link android.net.NetworkCapabilities}. Bn
to các đối tượng {@link android.net.NetworkRequest} bng lp {@link
android.net.NetworkRequest.Builder NetworkRequest.Builder}. {@link
android.net.ConnectivityManager#registerNetworkCallback(android.net.NetworkRequest,
android.net.ConnectivityManager.NetworkCallback) registerNetworkCallback()}
ri chuyn đối tượng{@link android.net.NetworkRequest} sang h thng. Khi
đáp ng được các điu kin mng, ng dng nhn lnh gi li để thc thi phương thc
{@link android.net.ConnectivityManager.NetworkCallback#onAvailable
onAvailable()} như được định nghĩa trong lp {@link
android.net.ConnectivityManager.NetworkCallback} ca nó.
</p>
<p>
ng dng tiếp tc nhn lnh gi li cho đến khi ng dng tn ti hoc nó gi
{@link android.net.ConnectivityManager#unregisterNetworkCallback
unregisterNetworkCallback()}.
</p>
<h2 id="media-broadcasts">
Các hn chế v NEW_PICTURE và NEW_VIDEO
</h2>
<p>
Trong N Developer Preview, ng dng không th gi hoc nhn các truyn phát {@link
android.hardware.Camera#ACTION_NEW_PICTURE} hoặc {@link
android.hardware.Camera#ACTION_NEW_VIDEO}. Hạn chế này giúp
loi b các tác động v hiu sut và tri nghim ca người dùng khi mt s ng dng phi
thc dy để x lý mt nh hoc video mi. N Developer Preview
m rng {@link android.app.job.JobInfo} và {@link
android.app.job.JobParameters} để cung cp mt gii pháp thay thế.
</p>
<h3 id="new-jobinfo">
Các phương thc JobInfo Mi
</h3>
<p>
Để kích hot tác v khi thay đổi URI ni dung, N Developer Preview s m rng
API{@link android.app.job.JobInfo} bng các phương thc sau:
</p>
<dl>
<dt>
{@code JobInfo.TriggerContentUri()}
</dt>
<dd>
Gói gn các tham s yêu cu để kích hot tác v khi thay đổi URI ni dung.
</dd>
<dt>
{@code JobInfo.Builder.addTriggerContentUri()}
</dt>
<dd>
Chuyn mt đối tượng {@code TriggerContentUri} đến {@link
android.app.job.JobInfo}. Mt {@link android.database.ContentObserver}
s theo dõi URI ni dung được gói gn. Nếu có nhiu đối tượng {@code
TriggerContentUri} được liên kết vi mt tác vụ, h thng s cung cp
lnh gi li ngay c khi h thng báo cáo có s thay đổi ch trong mt trong nhng URI ni dung.
</dd>
<dd>
Thêm c {@code TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS} để
kích hot tác v nếu bt k kế nhim nào ca URI đã cho thay đổi. C này
tương ng vi tham s {@code notifyForDescendants} đã chuyn đến {@link
android.content.ContentResolver#registerContentObserver
registerContentObserver()}.
</dd>
</dl>
<p class="note">
<strong>Lưu ý:</strong> {@code TriggerContentUri()} không th được s dng
kết hp vi {@link android.app.job.JobInfo.Builder#setPeriodic
setPeriodic()} hoc {@link android.app.job.JobInfo.Builder#setPersisted
setPersisted()}. Để tiếp tc theo dõi các thay đổi ni dung, hãy lên lch mt
{@link android.app.job.JobInfo} mi trước khi {@link
android.app.job.JobService} ca ng dng hoàn thành x lý lnh gi li gn đây nht.
</p>
<p>
Đon mã mu sau lên lch kích hot mt tác v khi h thng báo cáo
có s thay đổi v URI ni dung, {@code MEDIA_URI}:
</p>
<pre>
public static final int MY_BACKGROUND_JOB = 0;
...
public static void scheduleJob(Context context) {
JobScheduler js =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder builder = new JobInfo.Builder(
MY_BACKGROUND_JOB,
new ComponentName(context, MediaContentJob.class));
builder.addTriggerContentUri(
new JobInfo.TriggerContentUri(MEDIA_URI,
JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
js.schedule(builder.build());
}
</pre>
<p>
Khi h thng báo cáo có s thay đổi trong (các) URI ni dung được ch định, ng dng ca bn
s nhn được lnh gi li và mt đối tượng {@link android.app.job.JobParameters} được chuyn sang
phương thc {@link android.app.job.JobService#onStartJob onStartJob()}
trong {@code MediaContentJob.class}.
</p>
<h3 id="new-jobparam">
Các phương thc JobParameter Mi
</h3>
<p>
N Developer Preview cũng m rng {@link android.app.job.JobParameters} để
cho phép ng dng ca bn nhn thông tin hu ích v nhng gì thm quyn ni dung
và các URI đã kích hot tác vụ:
</p>
<dl>
<dt>
{@code Uri[] getTriggeredContentUris()}
</dt>
<dd>
Tr v mng URI đã kích hot tác v đó. Kết qu tr v có th bng {@code
null} nếu không có URI nào kích hot tác v (ví d như, tác v đã được
kích hot do thi hn hoc lý do khác), hoc s các URI
b thay đổi nhiu hơn 50.
</dd>
<dt>
{@code String[] getTriggeredContentAuthorities()}
</dt>
<dd>
Tr v mng xâu thm quyn ni dung đã kích hot tác v đó.
Nếu mng được tr v không phi {@code null}, hãy dùng {@code getTriggeredContentUris()}
để truy xut chi tiết v URI nào đã thay đổi.
</dd>
</dl>
<p>
Mã mu sau s ghi đè lên phương thc {@link
android.app.job.JobService#onStartJob JobService.onStartJob()} và
và ghi li các thm quyn ni dung và URI đã kích hot tác vụ.
</p>
<pre>
&#64;Override
public boolean onStartJob(JobParameters params) {
StringBuilder sb = new StringBuilder();
sb.append("Media content has changed:\n");
if (params.getTriggeredContentAuthorities() != null) {
sb.append("Authorities: ");
boolean first = true;
for (String auth :
params.getTriggeredContentAuthorities()) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(auth);
}
if (params.getTriggeredContentUris() != null) {
for (Uri uri : params.getTriggeredContentUris()) {
sb.append("\n");
sb.append(uri);
}
}
} else {
sb.append("(No content)");
}
Log.i(TAG, sb.toString());
return true;
}
</pre>
<h2 id="further-optimization">
Ti ưu hóa thêm ng dng ca bn
</h2>
<p>
Ti ưu hóa ng dng ca bn để chy trên các thiết b có b nh ít, hoc đang trong điu kin
b nh ít có th ci thin hiu sut và tri nghim ca người dùng. Loi b
các thành phn ph thuc trên các dch v chy ngm và b thu truyn phát không biu th đã đăng ký tĩnh
có th giúp ng dng ca bn chy tt hơn trên các thiết b như vy. Mc dù
N Developer Preview thc hin các bước để gim bt mt vài trong s các vn đề này, nhưng chúng tôi
khuyến ngh bn nên ti ưu ng dng ca bn để chy hoàn toàn không cn s dng
các tiến trình chy ngm này.
</p>
<p>
N Developer Preview gii thiu mt s lnh <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge (ADB)</a> b sung mà
bn có th s dng để kim th hành vi ca ng dng bng các tiến trình chy ngm đã b vô hiu hóa đó:
</p>
<ul>
<li>Để mô phng các điu kin trong đó các truyn phát không biu th và dch v chy ngm
không có sn, hãy nhp lnh sau:
</li>
<li style="list-style: none; display: inline">
<pre class="no-pretty-print">
{@code $ adb shell cmd appops set RUN_IN_BACKGROUND ignore}
</pre>
</li>
<li>Để kích hot li các truyn phát không biu th và dch v chy ngm, hãy nhp
lnh sau:
</li>
<li style="list-style: none; display: inline">
<pre class="no-pretty-print">
{@code $ adb shell cmd appops set RUN_IN_BACKGROUND allow}
</pre>
</li>
</ul>