2016-10-11 5 views
0

Meine Aktivität verwendet folgende OnCreate() mit einem ausführbaren Thread mit While-Schleife. Hier ist der Code:Android Runnable Thread stecken irgendwo

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(); 

    } 

Der Thread überprüft im Grunde für die DownFile, die von einem AWS-Dienst erstellt wird. Meine Aktivität läuft weiter und das Steuerelement tritt nicht in die While-Schleife ein. Die Bedingung ist zum ersten Mal wahr und danach tritt die Steuerung weder in die While-Schleife ein noch beendet sie diese. Die Anweisung vor der while-Schleife wird ordnungsgemäß protokolliert. MainActivity wird also nicht gestartet.

Ist dies eine falsche Implementierung von Threading? Ich verstehe nicht, was hier passiert.

Wenn ich die App stoppe und sie erneut ausführe, ist die Bedingung jetzt falsch und daher tritt das Steuerelement nicht in die while-Schleife ein, sondern die nächste Aktivität wird ordnungsgemäß geladen.

Antwort

1

Versuchen Handler-Klasse anstelle der Thread-Klasse. Es ist dafür gemacht.

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

Danke! Das hat auch funktioniert. –

+0

Freut mich zu hören! : D –

1

Verwenden Sie eine AsyncTask für das, was Sie tun, und Sie müssen nicht in einer endlosen While-Schleife stecken bleiben.

Eine vollständige Erklärung von ihnen hier mit: http://www.compiletimeerror.com/2013/01/why-and-how-to-use-asynctask.html

Und ich habe hier einen für grabbinf Bilder von einem Server implementiert: (Snippet) http://wlgfx.com/programming/tcp-android-client-and-server-code/

Auch Android ein Tutorial hat sie hier über die Verwendung : https://developer.android.com/reference/android/os/AsyncTask.html

Beispiel aus dem letzten Link:

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"); 
    } 
} 

Meine eigene Nutzung des 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

Ich habe AsyncTask in meiner Anwendung verwendet. Ich wollte wissen, was in meinem Code falsch ist. Oder ist Threading einfach nicht der richtige Weg? –

+0

Ihr Code-Snippet ist ein Thread, keine AsyncTask. Der Vorteil der AsyncTask ist die onPostExecute(), die nach Abschluss auf dem UI-Thread ausgeführt wird. – WLGfx

+0

Also das ist das Problem. Ich muss eine neue Aktivität im UI-Thread starten und nicht im Hintergrund-Thread. Durch die Verwendung von AsyncTask wurde das Problem behoben. Danke @WLGfx. –

Verwandte Themen