使用不同的布局保存方向更改的活动状态?

时间:2013-07-11 06:39:15

标签: android android-layout

我对同一个活动使用两个不同的布局,在方向更改时,不维护活动状态。请建议怎么做?

2 个答案:

答案 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

关于BroadcastReceivers

如果你想要一些东西让你开始这里是我在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>