android - 如何控制屏幕方向的变化?
ringa_lee
ringa_lee 2017-04-17 11:25:28
0
1
699

我的程序主要是控制后台线程的一些network activity,在启动之前,突然弹出了一个进度对话框,这个对话框是处理器上被驳回的。而当后台线程都运行的时候,对话框会弹出,此时,只要改变屏幕的方向,系统中的应用要么崩溃,要么死机,要么完全处于一种奇怪的运行状态中(平时只会出现在取消线程的情况中)。
我怎样才能成功的改变屏幕的方向?
下述代码可以大致描述程序运行的方式:

public class MyAct extends Activity implements Runnable {
    public ProgressDialog mProgress;

    // UI has a button that when pressed calls send

    public void send() {
         mProgress = ProgressDialog.show(this, "Please wait", 
                      "Please wait", 
                      true, true);
        Thread thread = new Thread(this);
        thread.start();
    }

    public void run() {
        Thread.sleep(10000);
        Message msg = new Message();
        mHandler.sendMessage(msg);
    }

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            mProgress.dismiss();
        }
    };
}

Stack:

E/WindowManager(  244): Activity MyAct has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@433b7150 that was originally added here
E/WindowManager(  244): android.view.WindowLeaked: Activity MyAct has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@433b7150 that was originally added here
E/WindowManager(  244):     at android.view.ViewRoot.<init>(ViewRoot.java:178)
E/WindowManager(  244):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:147)
E/WindowManager(  244):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:90)
E/WindowManager(  244):     at android.view.Window$LocalWindowManager.addView(Window.java:393)
E/WindowManager(  244):     at android.app.Dialog.show(Dialog.java:212)
E/WindowManager(  244):     at android.app.ProgressDialog.show(ProgressDialog.java:103)
E/WindowManager(  244):     at android.app.ProgressDialog.show(ProgressDialog.java:91)
E/WindowManager(  244):     at MyAct.send(MyAct.java:294)
E/WindowManager(  244):     at MyAct$4.onClick(MyAct.java:174)
E/WindowManager(  244):     at android.view.View.performClick(View.java:2129)
E/WindowManager(  244):     at android.view.View.onTouchEvent(View.java:3543)
E/WindowManager(  244):     at android.widget.TextView.onTouchEvent(TextView.java:4664)
E/WindowManager(  244):     at android.view.View.dispatchTouchEvent(View.java:3198)
E/WindowManager(  244):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:857)
E/WindowManager(  244):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:857)
E/WindowManager(  244):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:857)
E/WindowManager(  244):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:857)
E/WindowManager(  244):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:857)
E/WindowManager(  244):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1593)
E/WindowManager(  244):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1089)
E/WindowManager(  244):     at android.app.Activity.dispatchTouchEvent(Activity.java:1871)
E/WindowManager(  244):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1577)
E/WindowManager(  244):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1140)
E/WindowManager(  244):     at android.os.Handler.dispatchMessage(Handler.java:88)
E/WindowManager(  244):     at android.os.Looper.loop(Looper.java:123)
E/WindowManager(  244):     at android.app.ActivityThread.main(ActivityThread.java:3739)
E/WindowManager(  244):     at java.lang.reflect.Method.invokeNative(Native Method)
E/WindowManager(  244):     at java.lang.reflect.Method.invoke(Method.java:515)
E/WindowManager(  244):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
E/WindowManager(  244):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)

以及:

W/dalvikvm( 244): threadid=3: thread exiting with uncaught exception (group=0x4000fe68)

E/AndroidRuntime( 244): Uncaught handler: thread main exiting due to uncaught exception

E/AndroidRuntime( 244): java.lang.IllegalArgumentException: View not attached to window manager

E/AndroidRuntime( 244):   at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:331)

E/AndroidRuntime( 244):   at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:200)

E/AndroidRuntime( 244):   at android.view.Window$LocalWindowManager.removeView(Window.java:401)

E/AndroidRuntime( 244):   at android.app.Dialog.dismissDialog(Dialog.java:249)

E/AndroidRuntime( 244):   at android.app.Dialog.access$000(Dialog.java:59)

E/AndroidRuntime( 244):   at android.app.Dialog$1.run(Dialog.java:93)

E/AndroidRuntime( 244):   at android.app.Dialog.dismiss(Dialog.java:233)

E/AndroidRuntime( 244):   at MyAct$1.handleMessage(MyAct.java:321)

E/AndroidRuntime( 244):   at android.os.Handler.dispatchMessage(Handler.java:88)

E/AndroidRuntime( 244):   at android.os.Looper.loop(Looper.java:123)

E/AndroidRuntime( 244):   at android.app.ActivityThread.main(ActivityThread.java:3739)

E/AndroidRuntime( 244):   at java.lang.reflect.Method.invokeNative(Native Method)

E/AndroidRuntime( 244):   at java.lang.reflect.Method.invoke(Method.java:515)

E/AndroidRuntime( 244):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)

E/AndroidRuntime( 244):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)

E/AndroidRuntime( 244):   at dalvik.system.NativeStart.main(Native Method)

I/Process (  46): Sending signal. PID: 244 SIG: 3

I/dalvikvm( 244): threadid=7: reacting to signal 3

I/dalvikvm( 244): Wrote stack trace to '/data/anr/traces.txt'

I/Process ( 244): Sending signal. PID: 244 SIG: 9

I/ActivityManager(  46): Process MyAct (pid 244) has died.

我试图在onSaveInstanceState上取消对话框的进度条,但是这只能防止立即崩溃。后台线程仍然在运行,而且这个用户界面有一部分是处于拉伸状态的,需要杀掉整个应用程序才会重新开始工作。遇到这种情况,该怎么处理呢?

原问题:How to handle screen orientation change when progress dialog and background thread active?

ringa_lee
ringa_lee

ringa_lee

reply all(1)
小葫芦

Answer: Haseman
(Best answer)
When you change orientation, Android will create a new view (View). Your application may crash because your background thread is trying to change the scene on an old view. (It may also be problematic because your background thread is not on the UI thread)
I recommend changing the processor and updating when the orientation changes.


Answer: sonxurxo
You need to add the following code to the declaration of the control

android:configChanges="orientation"

Just like this

<activity android:label="@string/app_name"
        android:configChanges="orientation|keyboardHidden"
        android:name=".your.package">

When the configuration changes, the system destroys this control and a problem occurs. So putting the above code in the configuration file can prevent the system from destroying your control.


Answer: Pzanno
I ran into the same problem and came up with a solution that didn't involve using a ProgressDialog and got the results faster.
What I did was create a layout with a ProgressBar built in, as follows:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ProgressBar
    android:id="@+id/progressImage"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    />
</RelativeLayout>

Then do the following in onCreate

public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.progress);
}

Then do the task in the thread. When the task is completed and is in a runnable state, you can add the content view to the expected layout.
For example:

mHandler.post(new Runnable(){

public void run() {
        setContentView(R.layout.my_layout);
    } 
});
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template