我的活动的oncreate()方法中有一些线程。当方向改变时,线程再次重新启动(在每个方向改变时创建线程的新实例)。避免在方向更改时重新启动线程
我不想使用android:configChanges
或android:screenOrientation
。因为活动取决于方向。
我的活动的oncreate()方法中有一些线程。当方向改变时,线程再次重新启动(在每个方向改变时创建线程的新实例)。避免在方向更改时重新启动线程
我不想使用android:configChanges
或android:screenOrientation
。因为活动取决于方向。
使用android:configChanges
,但在overrided 方法只调用super.onConfigurationCanged()
方法(或不重写,通常)。
旋转时间onCreate()不会被调用,您的踏板不会重新启动,但您的布局将被旋转。
非常好。清除了我的困惑。 – Vivek 2012-01-29 16:57:31
我正在使用这种方法: 我在存储线程的活动中有一个字段。在onRetainNonConfigurationInstance()回答这个字段。它以这种方式得到保存,稍后可用于新活动的新实例。
在onStart()我从getLastNonConfigurationInstance()中获得线程。这可以是null(线程不是jet开始的),也可以是onRetainNonConfigurationInstance()保存的线程的引用。 如果您正在显示(并需要恢复)进度对话框,您还应该在线程中拥有一个状态(例如STARTED,RUNNING,DONE等)来处理onStart()中的进度显示。
如果您需要与线程进行通信,您可能需要注入处理程序(例如作为线程构造函数的参数)。
这里是一个例子。该线程从数据库中读取GPS数据以供日后后处理。我想只有在这里显示相关代码的省略方法的方法名称应该为themselfes说话,
这是所有从活动类:
private ProgressDialog progressDialog = null;
private LoadGpsDataThread loadGpsLogThread = null;
这是处理器用来沟通:
/**
* 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();
}
这里是启动逻辑:
@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();
}
这是线程的内部类:
/**
* 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");
}
}
想要了解更多关于屏幕定位维护的信息吗? – 2012-01-29 13:23:19