アクティビティのoncreate()メソッドにスレッドがいくつかあります。オリエンテーションが変更されると、スレッドが再び再開されます(スレッドが変更されるたびにスレッドの新しいインスタンスが作成されます)。オリエンテーションの変更でスレッドを再起動しないようにする
私はandroid:configChanges
またはandroid:screenOrientation
を使用しません。アクティビティはオリエンテーションに依存するためです。
アクティビティのoncreate()メソッドにスレッドがいくつかあります。オリエンテーションが変更されると、スレッドが再び再開されます(スレッドが変更されるたびにスレッドの新しいインスタンスが作成されます)。オリエンテーションの変更でスレッドを再起動しないようにする
私はandroid:configChanges
またはandroid:screenOrientation
を使用しません。アクティビティはオリエンテーションに依存するためです。
使用android:configChanges
が、オーバーライド方法でのみsuper.onConfigurationCanged()
メソッドを呼び出す(またはそれを上書きしません。
@Override
protected void onStart() {
if(DEBUG)
Log.d(TAG, "onStart");
super.onStart();
this.refreshData();
this.flightView.setText(this.flightDesc);
this.logView.setText(this.getGpsLogDescription());
this.statusView.setText(null);
this.initProfileSpinner();
// graphView is set asynchronously by the GPS data loading thread
// Get the last load thread and check whether it is still running
if (this.getLastNonConfigurationInstance() != null) {
this.loadGpsLogThread = (LoadGpsDataThread) this.getLastNonConfigurationInstance();
this.loadGpsLogThread.handler = this.progressHandler;
switch (this.loadGpsLogThread.state) {
case STATE_RUNNING:
// Show the progress dialog again
this.loadGpsData(true);
break;
case STATE_NOT_STARTED:
// Close the progress dialog in case it is open
this.dismissDialog(PROGRESS_DIALOG);
break;
case STATE_DONE:
this.loadGpsLogThread = null;
// Close the progress dialog in case it is open
this.dismissDialog(PROGRESS_DIALOG);
break;
default:
// Close the progress dialog in case it is open
// Get rid of the sending thread
if(DEBUG)
Log.d(TAG, "Unknown progress thread state");
this.dismissProgress();
}
}
else {
if(! this.globalState.detectorState.isGpsDataCacheAvailable(this.gpsFlight)) {
this.loadGpsData(false);
this.analysisResult = null;
}
else
// data already loaded
this.fillGraphView();
}
this.graphView.setShowLines(this.globalState.getBooleanPref(IPreferences.PREFS_GPS_GRAPH_LINES));
this.processSubActivityResult();
}
これは内部クラスとしてスレッドです一般的に)。
回転時にCreate()は呼び出されず、トレッドは再開されませんが、レイアウトは回転します。
非常に良い。私の混乱を解消した。 – Vivek
私はこのアプローチを使用しています: スレッドに格納されているアクティビティにフィールドがあります。 onRetainNonConfigurationInstance()でこのフィールドに答えます。この方法で保存され、後でアクティビティの新しいインスタンスで使用できます。
onStart()では、getLastNonConfigurationInstance()からスレッドを取得します。これは、null(スレッドはジェットが開始されていない)またはonRetainNonConfigurationInstance()によって保存されたスレッドへの参照です。 進行状況ダイアログを表示している場合(そして復元する必要がある場合)、onStart()の進行状況表示を復元するためのスレッド内の状態(STARTED、RUNNING、DONEなど)も必要です。
スレッドと通信する必要がある場合は、ハンドラを挿入することができます(スレッドのコンストラクタへのパラメータなど)。
ここは例です。スレッドは後で後処理するためにデータベースからGPSデータを読み込みます。
:これはハンドラであるprivate ProgressDialog progressDialog = null;
private LoadGpsDataThread loadGpsLogThread = null;
の通信に使用される:私は
これは、アクティビティクラスからのすべてのですが、省略メソッドのメソッド名は、themselfesのために話すべきで、ここでしか関連するコードを表示しようとしましたここで
/**
* This handler updates the progress dialog when the logged GPS data is loaded.
*/
final Handler progressHandler = new Handler() {
@Override
public void handleMessage(final Message msg) {
Bundle b;
switch(msg.arg2) {
case UPDATE_LOADER:
// Update from GPS data loading thread
final int total = msg.arg1;
if(GpsPostprocessingActivity.this.progressDialog != null)
GpsPostprocessingActivity.this.progressDialog.setProgress(total);
if(GpsPostprocessingActivity.this.loadGpsLogThread != null && GpsPostprocessingActivity.this.loadGpsLogThread.state == STATE_DONE) {
GpsPostprocessingActivity.this.dismissProgress();
GpsPostprocessingActivity.this.fillGraphView();
}
break;
case IGpsDataPostProccessor.STATUS_ANALYZER:
GpsPostprocessingActivity.this.statusView.setText(msg.arg1);
break;
case IGpsDataPostProccessor.UPDATE_ANALYZER:
int sample;
switch(msg.arg1) {
// ...
}
break;
case IGpsDataPostProccessor.GRAPH_UPDATE:
GpsPostprocessingActivity.this.fillGraphView();
break;
}
break;
}
}
};
は、コンストラクタのパラメータとしてハンドラに注意し、スレッドを開始する方法、次のとおりです。
/**
* Load the GPS data from the database.
* @param loading if <code>true</code> the load thread is already
* running. In this case only the progress dialog is opened.
*/
private void loadGpsData(final boolean loading) {
if(DEBUG)
Log.d(TAG, "loadGpsData: Loading GPS data, already loading = " + loading);
final int dataSize = this.gpsFlight.size();
final String title = this.globalState.getString(R.string.titel_load_gps_data);
final String msg = this.globalState.getFormattedTemplate(R.string.msg_tmpl_loading_gps_data, this.flightDesc);
this.showProgress(title, msg, dataSize);
if(! loading) {
this.loadGpsLogThread = new LoadGpsDataThread(this.progressHandler);
this.loadGpsLogThread.start();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
// Dialog is removed in onSaveInstanceState(), see comment there
// Check that there is a worker thread that
// needs preserving
if (this.loadGpsLogThread != null) {
// remove reference to this activity (important to avoid memory leak)
this.loadGpsLogThread.handler = null;
// Return the instance to be retained
if(DEBUG)
Log.d(TAG, "onRetainNonConfigurationInstance: saved process");
return this.loadGpsLogThread;
}
return super.onRetainNonConfigurationInstance();
}
ここでは
は開始論理である:、
/**
* This thread loads the GPS data from the database and
* updates the progress dialog via the handler.
*/
private class LoadGpsDataThread extends Thread {
Handler handler;
int state;
int stepsDone;
LoadGpsDataThread(final Handler h) {
this.handler = h;
this.state = STATE_NOT_STARTED;
}
@Override
public void run() {
this.state = STATE_RUNNING;
this.stepsDone = 0;
final Cursor c = GpsPostprocessingActivity.this.queryGpsData();
try {
while (c.moveToNext() && (this.state == STATE_RUNNING)) {
final TrackData row = GpsPostprocessingActivity.this.globalState.getDb().readGpsData(c);
GpsPostprocessingActivity.this.globalState.detectorState.gpsData[this.stepsDone] = row;
this.stepsDone += 1;
if(this.handler != null) {
// can be null if the activity has been destroyed
final Message msg = this.handler.obtainMessage();
msg.arg1 = this.stepsDone;
msg.arg2 = UPDATE_LOADER;
this.handler.sendMessage(msg);
}
}
}
finally {
this.state = STATE_DONE;
c.close();
}
if(DEBUG)
Log.d(TAG, "Data load thread finished");
}
}
画面の向きを維持したいのですか? –