我有一个活动,在加载时不需要来自服务器的数据 - 只需ui的简单初始化
UI有几个按钮。
用户点击其中一个,app向服务器发送请求(休息通话) 请求处理时显示微调器(约10秒)
现在它使用AsyncTask - 所以如果应用程序将纵向更改为横向 - 活动重新启动并且我松开了进程
第二个选项是使用Loader - 问题是它是在按钮点击时启动 - 而不是在活动开始时
这导致许多例外 - 当LoaderManager将事件发送到非启动项
时有没有解决方案?
几条评论: - 例如10秒 - 将用户锁定到一个方向不是一个选项 - 简单的休息电话服务是过度的
答案 0 :(得分:3)
public class TestActivity extends FragmentActivity {
private Button one;
private Button two;
private final int ONE_ID = 0;
private final int TWO_ID = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
one = (Button) findViewById(R.id.one);
two = (Button) findViewById(R.id.two);
one.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getLoaderManager().restartLoader(ONE_ID, null, callbacks);
}
});
two.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getLoaderManager().restartLoader(ONE_ID, null, callbacks);
}
});
Loader<AsyncTaskLoaderResult<Result>> loader = getLoaderManager().getLoader(ONE_ID);
if (loader != null) {
getLoaderManager().initLoader(ONE_ID, null, callbacks);
}
loader = getLoaderManager().getLoader(TWO_ID);
if (loader != null) {
getLoaderManager().initLoader(TWO_ID, null, callbacks);
}
}
public static class AsyncTaskLoaderResult<E> {
public E data;
public Bundle args;
}
public static class Result {
}
private LoaderManager.LoaderCallbacks<AsyncTaskLoaderResult<Result>> callbacks = new LoaderManager.LoaderCallbacks<AsyncTaskLoaderResult<Result>>() {
@Override
public Loader<AsyncTaskLoaderResult<Result>> onCreateLoader(int id, Bundle args) {
/**
* according different Id, create different AsyncTaskLoader
*/
switch (id) {
case ONE_ID:
return new OneAsyncTaskLoader(TestActivity.this);
case TWO_ID:
return new TwoAsyncTaskLoader(TestActivity.this);
}
return null;
}
@Override
public void onLoadFinished(Loader<AsyncTaskLoaderResult<Result>> loader, AsyncTaskLoaderResult<Result> data) {
/**
* handle result
*/
switch (loader.getId()) {
}
getLoaderManager().destroyLoader(loader.getId());
}
@Override
public void onLoaderReset(Loader<AsyncTaskLoaderResult<Result>> loader) {
}
};
public static class OneAsyncTaskLoader extends AsyncTaskLoader<AsyncTaskLoaderResult<Result>> {
private AsyncTaskLoaderResult<Result> result;
public OneAsyncTaskLoader(Context context) {
super(context);
}
@Override
protected void onStartLoading() {
super.onStartLoading();
if (result != null) {
deliverResult(result);
} else {
forceLoad();
}
}
@Override
public AsyncTaskLoaderResult<Result> loadInBackground() {
/**
* send request to server
*/
result = new AsyncTaskLoaderResult<Result>();
result.data = null; // result.data comes from server's response
return result;
}
}
public static class TwoAsyncTaskLoader extends AsyncTaskLoader<AsyncTaskLoaderResult<Result>> {
private AsyncTaskLoaderResult<Result> result;
public TwoAsyncTaskLoader(Context context) {
super(context);
}
@Override
protected void onStartLoading() {
super.onStartLoading();
if (result != null) {
deliverResult(result);
} else {
forceLoad();
}
}
@Override
public AsyncTaskLoaderResult<Result> loadInBackground() {
/**
* send request to server
*/
result = new AsyncTaskLoaderResult<Result>();
result.data = null; // result.data comes from server's response
return result;
}
}
}
答案 1 :(得分:0)
首先,您可以通过声明来消除orienatation更改问题
android:configChanges="orientation"
但真正的问题是让用户盯着旋转器10秒钟。大多数用户对此没有足够的耐心。我不知道你的应用程序在做什么,所以很难给出准确的建议,但我可以说你需要在AsyncTask
中做你的网络内容,但允许用户做其他事情
您可以允许用户在AsyncTask
完成时执行其他操作或将该代码放入[服务(http://developer.android.com/guide/components/services.html)中。无论哪种方式,都不要让你的用户盯着屏幕进行10秒的旋转......他们不会长时间成为你的用户
答案 2 :(得分:0)
如果您使用的是AsyncTask
,则可能需要使用Service
或使用onRetainNonConfigurationInstance或Fragment.setRetainInstance
来AsyncTask
完成配置更改。
或者禁用配置更改:我过去曾使用过这种方法并取得了一些成功。
答案 3 :(得分:0)
这是一篇关于这个主题的好文章:
http://www.javacodegeeks.com/2013/01/android-loaders-versus-asynctask.html
无论如何,正如@codeMagic所提到的,AsyncTask
android:configChanges="orientation|screenSize"
应该足够(它可以防止在配置更改时重新创建活动)