Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在旋转前进行网络调用时,如何更新UI线程?_Android_Handler_Threadpool - Fatal编程技术网

Android 在旋转前进行网络调用时,如何更新UI线程?

Android 在旋转前进行网络调用时,如何更新UI线程?,android,handler,threadpool,Android,Handler,Threadpool,好吧,这让我快发疯了。我有一个工作线程(网络调用),需要单独运行UI线程(它实际上是一个ThreadPoolExecutor,但我简化了它以证明我的观点)。如果在纵向运行此代码而不旋转,则文本将更新。我把延迟放在那里,以允许旋转来显示我的问题。如果从纵向开始,在文本更新旋转到横向之前,文本不会更新。如果您对代码进行注释,您可以看到侦听器启动,但文本永远不会更新 我试图模拟一个在单独线程中运行的自定义网络调用,如果用户在这两个线程之间旋转,那么可能需要一些时间才能返回,然后数据就会丢失。我们正试图

好吧,这让我快发疯了。我有一个工作线程(网络调用),需要单独运行UI线程(它实际上是一个ThreadPoolExecutor,但我简化了它以证明我的观点)。如果在纵向运行此代码而不旋转,则文本将更新。我把延迟放在那里,以允许旋转来显示我的问题。如果从纵向开始,在文本更新旋转到横向之前,文本不会更新。如果您对代码进行注释,您可以看到侦听器启动,但文本永远不会更新

我试图模拟一个在单独线程中运行的自定义网络调用,如果用户在这两个线程之间旋转,那么可能需要一些时间才能返回,然后数据就会丢失。我们正试图阻止多个网络呼叫以节省手机上的数据使用

package com.example.test;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.res.Configuration;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    int orientation = getResources().getConfiguration().orientation; 
    if (Configuration.ORIENTATION_LANDSCAPE == orientation) { 
        //Do SomeThing; // Landscape
    } else { 
        startBackgroundWork();
        //Do SomeThing;  // Portrait
    } 

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

private Handler mHandler = new Handler();

public void startBackgroundWork() {
    new WorkingThread(new SomeListener() {
        public void onSomethingDone(final Object result) {

            mHandler.post(new Runnable() {
                public void run() { 
                    ((TextView)findViewById(R.id.text)).setText((String)result);
                    //showMyDialog(result); 
                }
            });

        }    
    }).start();
}

public interface SomeListener {
    public void onSomethingDone(Object result);
}

public class WorkingThread extends Thread {
    private SomeListener mListener;

    public WorkingThread(SomeListener listener) {
        mListener = listener;
    }

    public void run() {
        /* do some work */
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mListener.onSomethingDone("New Text");
    }
}
}

这是因为在循环时,活动被重新创建,因此所有代码都绑定到旧活动。您应该参考您的工作线程:

private static WorkingThread mWorkingThread;
public void startBackgroundWork() {
    mWorkingThread = new WorkingThread(new SomeListener() {
        public void onSomethingDone(final Object result) {

            mHandler.post(new Runnable() {
                public void run() { 
                    ((TextView)findViewById(R.id.text)).setText((String)result);
                    //showMyDialog(result); 
                }
            });

        }    
    }).start();
}
然后,一旦创建并更新它:

public class WorkingThread extends Thread {
    private SomeListener mListener;

    public WorkingThread(SomeListener listener) {
        mListener = listener;
    }

    public void run() {
        /* do some work */
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mListener.onSomethingDone("New Text");
    }

    public void updateListener(SomeListener listener) {
        mListener = listener;
    }
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startBackgroundWork();
}

public void startBackgroundWork() {
    if (mWorkingThread == null || mWorkingThread.isFinished()) { // Use a boolean to know if it still running


    mWorkingThread  = new WorkingThread(new SomeListener() {
        public void onSomethingDone(final Object result) {

            mHandler.post(new Runnable() {
                public void run() { 
                    ((TextView)findViewById(R.id.text)).setText((String)result);
                    //showMyDialog(result); 
                }
            });

        }    
    });
        mWorkingThread.start();

    } else { 
        mWorkingThread.updateListener(new SomeListener() {
        public void onSomethingDone(final Object result) {

            mHandler.post(new Runnable() {
                public void run() { 
                    ((TextView)findViewById(R.id.text)).setText((String)result);
                    //showMyDialog(result); 
                }
            });

        }    
    });
    } 
}
但是你可以做一些改进:

  • WorkingRead类应该是静态的,以避免直接引用旧活动:

  • 然后引用当前活动,并在重新创建时更新它

  • 创建一个更新文本的方法,而不是将代码直接放在侦听器中


    • 这是因为在轮换时,活动被重新创建,因此您的所有代码都绑定到旧活动。您应该参考您的工作线程:

      private static WorkingThread mWorkingThread;
      public void startBackgroundWork() {
          mWorkingThread = new WorkingThread(new SomeListener() {
              public void onSomethingDone(final Object result) {
      
                  mHandler.post(new Runnable() {
                      public void run() { 
                          ((TextView)findViewById(R.id.text)).setText((String)result);
                          //showMyDialog(result); 
                      }
                  });
      
              }    
          }).start();
      }
      
      然后,一旦创建并更新它:

      public class WorkingThread extends Thread {
          private SomeListener mListener;
      
          public WorkingThread(SomeListener listener) {
              mListener = listener;
          }
      
          public void run() {
              /* do some work */
              try {
                  Thread.sleep(10000);
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              mListener.onSomethingDone("New Text");
          }
      
          public void updateListener(SomeListener listener) {
              mListener = listener;
          }
      }
      
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          startBackgroundWork();
      }
      
      public void startBackgroundWork() {
          if (mWorkingThread == null || mWorkingThread.isFinished()) { // Use a boolean to know if it still running
      
      
          mWorkingThread  = new WorkingThread(new SomeListener() {
              public void onSomethingDone(final Object result) {
      
                  mHandler.post(new Runnable() {
                      public void run() { 
                          ((TextView)findViewById(R.id.text)).setText((String)result);
                          //showMyDialog(result); 
                      }
                  });
      
              }    
          });
              mWorkingThread.start();
      
          } else { 
              mWorkingThread.updateListener(new SomeListener() {
              public void onSomethingDone(final Object result) {
      
                  mHandler.post(new Runnable() {
                      public void run() { 
                          ((TextView)findViewById(R.id.text)).setText((String)result);
                          //showMyDialog(result); 
                      }
                  });
      
              }    
          });
          } 
      }
      
      但是你可以做一些改进:

      • WorkingRead类应该是静态的,以避免直接引用旧活动:

      • 然后引用当前活动,并在重新创建时更新它

      • 创建一个更新文本的方法,而不是将代码直接放在侦听器中


      这不起作用,因为每次旋转时都会触发startbackground,如果在代码更改的情况下输入方向代码,则它会执行与以前相同的操作。观察线程启动,您将看到两个工作线程正在运行。我修改了startBackgroundWork,如果线程已经在运行(例如,在方向已更改的情况下),则startBackgroundWork只需更新侦听器即可(我想我可能应该为此创建另一个方法,但您可以稍后再这样做)。它之所以有效,是因为mWorkingThread是一个静态实例,在旋转时保留。(不管怎样,我想你明白了,因为你接受了我的答案)这不起作用,因为每次旋转都会触发startbackground,如果你输入方向代码并更改代码,那么它会做与以前相同的事情。观察线程启动,您将看到两个工作线程正在运行。我修改了startBackgroundWork,如果线程已经在运行(例如,在方向已更改的情况下),则startBackgroundWork只需更新侦听器即可(我想我可能应该为此创建另一个方法,但您可以稍后再这样做)。它之所以有效,是因为mWorkingThread是一个静态实例,在旋转时保留。(不管怎么说,我想你明白了,因为你接受了我的答案)