Android runnable线程卡在某处

时间:2016-10-11 17:01:36

标签: java android multithreading

My Activity正在使用带有while循环的Runnable线程的onCreate()。这是代码:

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循环之前的语句。所以,基本上MainActivity并没有开始。

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

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

2 个答案:

答案 0 :(得分:1)

使用AsyncTask来处理你正在做的事情,你不必陷入无休止的循环中。

在此处使用它们的完整说明:ImageJ

我已经在服务器上为grabbinf图像实现了一个:(下面的代码片段) http://www.compiletimeerror.com/2013/01/why-and-how-to-use-asynctask.html

甚至Android都有一个关于在这里使用它们的教程: http://wlgfx.com/programming/tcp-android-client-and-server-code/

最后一个链接的例子:

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

我自己使用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();
        }
    }
}

答案 1 :(得分: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);

    }