2016-10-11 52 views
0

我的活动正在使用以下onCreate()和带有while循环的Runnable线程。这里是代码:Android可运行线程卡住某处

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_post_user_registration); 

     SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 
     SharedPreferences.Editor editor = sp.edit(); 

     //Some Async task here 

     final File destFile = new File(filesDir, sp.getString(Constants.SharedPreferences.USER_ID,null)+ Constants.S3Bucket.IMAGE_EXTENSION); 
     final File downFile = new File(filesDir, Constants.S3Bucket.USER_DIRECTORY + sp.getString(Constants.SharedPreferences.USER_ID,null)+ Constants.S3Bucket.IMAGE_EXTENSION); 
     Runnable myRunnable = new Runnable() { 


      @Override 
      public void run() { 

       Log.v(LOG_TAG,"S3 file profile exists "+downFile.getAbsolutePath()+" "+downFile.exists()); 

       while(!downFile.exists()){ 
        try { 
         Thread.sleep(1000); 
        } catch (InterruptedException e) { 
         Log.e(LOG_TAG,"Error",e); 

        } 
        Log.v(LOG_TAG,"Inside while loop"); 
       } 

       Log.v(LOG_TAG,"S3 file profile exists after while "+downFile.getAbsolutePath()+" "+downFile.exists()); 


       Intent intent = new Intent(getApplicationContext(), MainActivity.class); 
       startActivity(intent); 
       finish(); 
      } 
     }; 
     Thread myThread = new Thread(myRunnable); 
     myThread.start(); 

    } 

线程基本上检查正在由AWS服务创建的downFile。我的活动继续运行,并且控制不会在循环中输入。该条件第一次是真实的,之后控制器既不进入while循环也不退出。 while循环之前的语句正确记录。所以,基本上MainActivity并没有开始。

这是一个错误的线程执行?我不明白这里发生了什么。

如果我停止应用程序并再次运行它,则现在条件为false,因此控件不会在while循环中输入,但下一个Activity会正确加载。

回答

1

尝试使用Handler类,而不是Thread类。它是为此而制作的。

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_post_user_registration); 

     SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 
     SharedPreferences.Editor editor = sp.edit(); 

     //Some Async task here 

     final File destFile = new File(filesDir, sp.getString(Constants.SharedPreferences.USER_ID,null)+ Constants.S3Bucket.IMAGE_EXTENSION); 
     final File downFile = new File(filesDir, Constants.S3Bucket.USER_DIRECTORY + sp.getString(Constants.SharedPreferences.USER_ID,null)+ Constants.S3Bucket.IMAGE_EXTENSION); 
     Runnable myRunnable = new Runnable() { 

      @Override 
      public void run() { 

       Log.v(LOG_TAG,"S3 file profile exists "+downFile.getAbsolutePath()+" "+downFile.exists()); 

       while(!downFile.exists()){ 
        try { 
         Thread.sleep(1000); 
        } catch (InterruptedException e) { 
         Log.e(LOG_TAG,"Error",e); 

        } 
        Log.v(LOG_TAG,"Inside while loop"); 
       } 

       Log.v(LOG_TAG,"S3 file profile exists after while "+downFile.getAbsolutePath()+" "+downFile.exists()); 


       Intent intent = new Intent(getApplicationContext(), MainActivity.class); 
       startActivity(intent); 
       finish(); 
      } 
     }; 

     Handler handler = new Handler(); 
     handler.post(myRunnable); 

    } 
+0

谢谢!这也有效。 –

+0

很高兴听到! :d –

1

使用AsyncTask来处理你正在做的事情,而且你不必被困在无尽的while循环中。

这里使用它们的完整解释:http://www.compiletimeerror.com/2013/01/why-and-how-to-use-asynctask.html

而且我实现了一个从服务器这里grabbinf图片:(以下摘录) http://wlgfx.com/programming/tcp-android-client-and-server-code/

即使Android已经在这里使用他们的教程:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { 
    protected Long doInBackground(URL... urls) { 
     int count = urls.length; 
     long totalSize = 0; 
     for (int i = 0; i < count; i++) { 
      totalSize += Downloader.downloadFile(urls[i]); 
      publishProgress((int) ((i/(float) count) * 100)); 
      // Escape early if cancel() is called 
      if (isCancelled()) break; 
     } 
     return totalSize; 
    } 

    protected void onProgressUpdate(Integer... progress) { 
     setProgressPercent(progress[0]); 
    } 

    protected void onPostExecute(Long result) { 
     showDialog("Downloaded " + result + " bytes"); 
    } 
} 
:从最后一个环节 https://developer.android.com/reference/android/os/AsyncTask.html

例子

我自己用的AsynTask的...

public class GetImageFromServer extends AsyncTask<Void, Void, Bitmap> { 

    private final String tag = "WLGFX-AsyncBitmap"; 

    private Context context; 
    private ImageView imageView; 
    private int width; 
    private int height; 

    GetImageFromServer(Context ctx, ImageView view) { 
     context = ctx; 
     imageView = view; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     imageView.setImageBitmap(null); 
     width = imageView.getWidth(); 
     height = imageView.getHeight(); 
    } 

    @Override 
    protected void onPostExecute(Bitmap bitmap) { 
     super.onPostExecute(bitmap); 
     imageView.setImageBitmap(bitmap); 

     Log.d(tag, "Bitmap: " + 
     "(" + bitmap.getWidth() + 
     "," + bitmap.getHeight() + ")" + 
     " " + bitmap.getByteCount()); 
    } 

    @Override 
    protected Bitmap doInBackground(Void... voids) { 
     String head = "GSIF"; 
     byte[] header_data = head.getBytes(); 

     try { 
      InetAddress address = InetAddress.getByName(Global.server_host); 

      Socket socket = new Socket(address, Global.tcp_port); 
      OutputStream out = socket.getOutputStream(); 
      out.write(header_data); 

      byte[] dim = new byte[2]; 

      dim[0] = (byte)(width >> 8); 
      dim[1] = (byte)width; 
      out.write(dim); 

      dim[0] = (byte)(height >> 8); 
      dim[1] = (byte)(height); 
      out.write(dim); 

      byte[] length = new byte[4]; 
      readSocketBytes(socket, length); 

      int size = (length[0] & 255) << 24 | 
        (length[1] & 255) << 16 | 
        (length[2] & 255)<< 8 | 
        length[3] & 255; 

      byte[] image_data = new byte[size]; 
      readSocketBytes(socket, image_data); 

      Bitmap bitmap = BitmapFactory.decodeByteArray(image_data, 0, size); 

      socket.close(); 

      return bitmap; 
     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    private void readSocketBytes(Socket socket, byte[] data) throws IOException { 
     int length = data.length; 
     InputStream in = socket.getInputStream(); 
     int position = 0; 

     while (position < length) { 
      int count = in.read(data, position, length - position); 
      if (count > 0) position += count; 
      else throw new IOException(); 
     } 
    } 
} 
+0

我在我的应用程序中使用了AsyncTask。我想知道我的代码中有什么问题。或者是线程不正确的做法呢? –

+0

你的代码片段是一个线程,而不是一个AsyncTask。 AsyncTask的好处是onPostExecute()在完成时将在UI线程上运行。 – WLGfx

+0

所以这就是问题所在。我需要在UI线程上启动新的Activity,而不是在后台线程上。使用AsyncTask解决了这个问题。谢谢@WLGfx。 –