gpt4 book ai didi

Android AsyncTask ProgressDialog轮换配置不同

转载 作者:行者123 更新时间:2023-11-30 04:01:43 24 4
gpt4 key购买 nike

我已经设法在屏幕旋转期间使用带有不确定进度条的 Asynctask。 Asynctask 只启动一次,进度条按照我的意愿在旋转时恢复。

我有不同的纵向布局和布局方向。布局包括一个按钮和一个 TextView 。 layout-land 中 textview 的大小和文本颜色不同。方向是横向。

问题是当我在 asynctask 运行时旋转屏幕时,它无法在 onPostExecute 方法中更新 textview。当我旋转时,它会使用 layout-land 文件重新创建 Activity 。但为什么我不能更新我的 Textview?

layout\activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Button
android:text="Start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startClicked"
/>
<TextView
android:id="@+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
tools:context=".MainActivity" />

</LinearLayout>

layout-land\activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<Button
android:text="Start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startClicked"
/>
<TextView
android:textSize="36dp"
android:textColor="#ff0000"
android:id="@+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
tools:context=".MainActivity" />

</LinearLayout>

MainActivity.java:

package com.example.asynctaskconfig;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
static String data;
static ProgressDialog pd;
MyAsyncTask task;
TextView tv;

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);

tv = (TextView) findViewById(R.id.hello);

if (getLastNonConfigurationInstance() != null) {
task = (MyAsyncTask) getLastNonConfigurationInstance();
if (task != null) {
if (!(task.getStatus().equals(AsyncTask.Status.FINISHED))) {
showProgressDialog();
}
}
}
}

@Override
public Object onRetainNonConfigurationInstance() {
if (pd != null)
pd.dismiss();
if (task != null)
return (task);
return super.onRetainNonConfigurationInstance();
}


private void showProgressDialog() {
if (pd == null || !pd.isShowing()) {
pd = new ProgressDialog(MainActivity.this);
pd.setIndeterminate(true);
pd.setTitle("DOING..");
pd.show();
}
}

private void dismissProgressDialog() {
if (pd != null && pd.isShowing())
pd.dismiss();
}

public class MyAsyncTask extends AsyncTask<String, Void, Boolean> {
@Override
protected void onPreExecute() {
showProgressDialog();
}

@Override
protected Boolean doInBackground(String... args) {
try {
Thread.sleep(5000);
data = "result from ws";
} catch (Exception e) {
return true;
}
return true;
}

protected void onPostExecute(Boolean result) {
if (result) {
dismissProgressDialog();
updateUI();
}
}
}

private void updateUI() {
tv.setText(data == null ? "null" : data);
}

public void startClicked(View target) {
task = new MyAsyncTask();
task.execute("start");
}
}

最佳答案

我的做法如下:

1-android:freezesText="true" 添加到我所有的 TextView。这使 TextView 能够在配置更改时保存它们的状态。

2- 使您的 AsyncTask 成为静态内部类。

3- 修改AsyncTask 以保留对它所在的Activity 的引用。因此AsyncTask 可以通过此引用访问Activity 的UI 小部件。

4- 在这里,在屏幕旋转期间保持有效的 Activity 引用很重要。因此,重写 onDestroy 方法并将 Activity 与 AsyncTask 解除绑定(bind)。因此,任务不会保留旧的(已死亡的) Activity 。

5-onRetainNonConfigurationInstance 中,如果任务仍在运行,则使用当前 Activity 更新其 Activity 引用,以便它成功绑定(bind)到新 Activity 。

6- 最后,在onPostExecuteMethod中,通过 Activity 引用访问 Activity 的UI元素。

完整的工作解决方案:

layout\activity_main.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Button
android:text="Start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startClicked"
/>
<TextView
android:freezesText="true"
android:id="@+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
tools:context=".MainActivity" />
</LinearLayout>

layout-land\activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<Button
android:text="Start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startClicked"
/>
<TextView
android:freezesText="true"
android:textSize="36dp"
android:textColor="#ff0000"
android:id="@+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
tools:context=".MainActivity" />
</LinearLayout>

MainActivity.java:

package com.example.asynctaskconfig;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
static ProgressDialog pd;
MyAsyncTask task;
TextView tv;

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);

tv = (TextView) findViewById(R.id.hello);

if (getLastNonConfigurationInstance() != null) {
task = (MyAsyncTask) getLastNonConfigurationInstance();
if (task != null) {
task.activity = this;
if (!(task.getStatus().equals(AsyncTask.Status.FINISHED))) {
showProgressDialog();
}
}
}
}

@Override
protected void onDestroy() {
super.onDestroy();
if (task != null) {
task.activity = null;
}
}

@Override
public Object onRetainNonConfigurationInstance() {
if (pd != null)
pd.dismiss();
if (task != null)
return (task);
return super.onRetainNonConfigurationInstance();
}

private void showProgressDialog() {
if (pd == null || !pd.isShowing()) {
pd = new ProgressDialog(MainActivity.this);
pd.setIndeterminate(true);
pd.setTitle("DOING..");
pd.show();
}
}

private void dismissProgressDialog() {
if (pd != null && pd.isShowing())
pd.dismiss();
}

static class MyAsyncTask extends AsyncTask<String, Void, String> {
MainActivity activity;

public MyAsyncTask(MainActivity activity) {
this.activity = activity;
}

@Override
protected void onPreExecute() {
activity.showProgressDialog();
}
@Override
protected String doInBackground(String... args) {
try {
Thread.sleep(8000);
return "data from ws";
} catch (Exception e) {
return "exception";
}
}

protected void onPostExecute(String result) {
activity.dismissProgressDialog();
activity.tv.setText(result == null ? "null" : result);
}
}

public void startClicked(View target) {
task = new MyAsyncTask(this);
task.execute("start");
}
}

关于Android AsyncTask ProgressDialog轮换配置不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12390657/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com