我对同一个活动使用两个不同的布局,在方向更改时,不维护活动状态。请建议怎么做?
答案 0 :(得分:2)
您可以使用onSavedInstanceState轻松存储“活动状态”。例如:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(saveInstanceState != null) {
if(savedInstanceState.getBoolean("running") == true) {
// previously is running
} else {
// previously not running
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if(condition) {
outState.putBoolean("running", true);
}
}
答案 1 :(得分:0)
您似乎在AsyncTask
中做了一些工作,然后您正在改变方向。
将您正在执行的任务从AsyncTask
移至IntentService
。执行作业后,发送包含结果的广播。在您的活动中,在BroadcastReceiver
中注册onCreate
,然后在onDestroy
中取消注册。
该接收器将处理您的操作结果。您还可以从IntentService
发送一些可由同一接收方接收和处理的中间数据/进度更新。
编辑以显示一些代码。
Google first search result教程的IntentService
。但我强烈建议您阅读有关Services
的更多信息。 Vogella也有一篇很好的文章about this。
如果你想要一些东西让你开始这里是我在15分钟内建立的一个示例项目:
activity
:
package com.adip.droid.sampleandroid;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
public class FrontActivity extends FragmentActivity {
private TextView labelData;
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WorkerService.WORK_PROGRESS_ACTION.equals(action)) {
publishProgress(intent.getStringExtra(WorkerService.WORK_KEY_PROGRESS));
} else if (WorkerService.WORK_END_ACTION.equals(action)) {
workInProgress = false;
publishResult(intent.getStringExtra(WorkerService.WORK_KEY_RESULT));
}
}
};
protected void publishProgress(String data) {
showMessage(data);
}
protected void publishResult(String data) {
showMessage(data);
}
private void showMessage(String data) {
labelData.setText(data);
}
/**
* Maybe you need this in order to not start the service once you have an ongoing job ...
* */
private boolean workInProgress;
@Override
protected void onCreate(Bundle instanceState) {
super.onCreate(instanceState);
setContentView(R.layout.front_layout);
if (instanceState != null) {
workInProgress = instanceState.getBoolean("WORK_IN_PROGRESS", false);
}
labelData = (TextView) findViewById(R.id.labelData);
findViewById(R.id.btnWorker).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
doTheJob();
}
});
IntentFilter filter = new IntentFilter(WorkerService.WORK_END_ACTION);
filter.addAction(WorkerService.WORK_PROGRESS_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
}
protected void doTheJob() {
if (workInProgress) {
return;
}
Intent serviceIntent = new Intent(this, WorkerService.class);
serviceIntent.setAction(WorkerService.WORK_START_ACTION);
startService(serviceIntent);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("WORK_IN_PROGRESS", workInProgress);
}
@Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
}
其布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btnWorker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Start the work" />
<TextView
android:id="@+id/labelData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/btnWorker"
android:layout_centerHorizontal="true"
android:layout_marginBottom="35dp"
android:freezesText="true"
android:text="No data yet"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
和IntentService
:
package com.adip.droid.sampleandroid;
import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
public class WorkerService extends IntentService {
public static final String WORK_START_ACTION = "WORK_START_ACTION";
public static final String WORK_END_ACTION = "WORK_END_ACTION";
public static final String WORK_KEY_RESULT = "WORK_KEY_RESULT";
public static final String WORK_PROGRESS_ACTION = "WORK_PROGRESS_ACTION";
public static final String WORK_KEY_PROGRESS = "WORK_KEY_PROGRESS";
public WorkerService() {
super("WorkerService");
}
@Override
protected void onHandleIntent(Intent intent) {
if (WORK_START_ACTION.equals(intent.getAction())) {
startProgress();
}
}
private void startProgress() {
publishProgress("Starting the job");
synchronized (this) {
try {
wait(2500);
} catch (InterruptedException ignored) {
}
}
publishProgress("Progress Point A");
synchronized (this) {
try {
wait(2500);
} catch (InterruptedException ignored) {
}
}
publishJobDone();
}
public void publishProgress(String data) {
Intent progressIntent = new Intent(WORK_PROGRESS_ACTION);
progressIntent.putExtra(WORK_KEY_PROGRESS, data);
LocalBroadcastManager.getInstance(this).sendBroadcast(progressIntent);
}
public void publishJobDone() {
Intent progressIntent = new Intent(WORK_END_ACTION);
progressIntent.putExtra(WORK_KEY_RESULT, "Job done!");
LocalBroadcastManager.getInstance(this).sendBroadcast(progressIntent);
}
}
另外请不要忘记更新清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.adip.droid.sampleandroid"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".FrontActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".WorkerService"
android:exported="false" >
</service>
</application>
</manifest>