通过Thread初始化全局变量

时间:2017-02-22 13:25:00

标签: android multithreading

我是Android的新手。我在Main类中有一个全局变量:

public class MainActivity extends AppCompatActivity {
private int lenghtOfFile;

我创建了一个AsyncTask来连接Internet并从下载链接获取文件大小:

   private class GetSizeOfFile extends AsyncTask<String, Void,Integer> {

    @Override
    protected  Integer doInBackground(String... stringURls) {
        String stringURl = stringURls[0];
        Log.i("===", "doInBackground: " + stringURl);

        try {
            URL url = new URL(stringUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            lenghtOfFile = connection.getContentLength();


        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return lenghtOfFile;
    }

    @Override
    protected void onPostExecute(Integer lenghtOfFile) {
        super.onPostExecute(lenghtOfFile);

            Log.i("====", "size of file in Thread: " + lenghtOfFile);

    }
}

当我登录线程时,我的全局变量已被初始化:

Log.i("====", "size of file in Thread: " + lenghtOfFile);

但是我的方法是我执行了这个线程我的全局变量还没有被初始化,它的值是0?

        new GetSizeOfFile().execute(stringUrl);

    Log.i("====", "size of file after Thread: " + lenghtOfFile);`

我的logcat:

02-22 13:20:26.516 8167-8167/com.example.manifest.simplefiledownloadmanager I/===: addURLToList: http://cdn.p30download.com/?b=p30dl-software&f=VLC.Media.Player.v2.2.4.x64_p30download.com.rar
02-22 13:20:26.516 8167-8167/com.example.manifest.simplefiledownloadmanager I/====: file name : ?b=p30dl-software&f=VLC.Media.Player.v2.2.4.x64_p30download.com.rar
02-22 13:20:26.516 8167-8167/com.example.manifest.simplefiledownloadmanager I/====: size of file after Thread: 0
02-22 13:20:26.516 8167-8306/com.example.manifest.simplefiledownloadmanager I/===: doInBackground: http://cdn.p30download.com/?b=p30dl-software&f=VLC.Media.Player.v2.2.4.x64_p30download.com.rar
02-22 13:20:32.836 8167-8167/com.example.manifest.simplefiledownloadmanager I/====: size of file in Thread: 33344550

在初始化线程中的几秒lenghtOfFile之后。我怎么能做一些工作,在这一行我从线程得到正确的文件大小? Log.i("====", "size of file after Thread: " + lenghtOfFile);

2 个答案:

答案 0 :(得分:0)

这是因为主线程中的Log命令发生在AsyncTask中的Log命令之前。

任务被发送到baqckground运行,主要任务继续快乐。

这可以通过日志行本身的时间在logcat中清楚地看到。

02-22 13:20:26.516 8167-8167/com.example.manifest.simplefiledownloadmanager I/====: size of file after Thread: 0

02-22 13:20:32.836 8167-8167/com.example.manifest.simplefiledownloadmanager I/====: size of file in Thread: 33344550

注意线程中的那个如何发生。

答案 1 :(得分:0)

您必须等待lenghtOfFile更新。这可能需要任意时间,可能根本不会发生(如果有错误)。因此,最好的方法是不要等待它更新,而是在更新后得到通知。一个明智的解决方案是使用观察者模式(tutorial featuring PropertyChangeEventtutorial with RxJava)。另一种可能性是使用像EventBus这样的事件总线。如果您只有一个需要通知的组件,可以直接从onPostExecute(Integer lenghtOfFile)拨打电话。

如果您真的想等待lengthOfFile更新,请使用CountDownLatch之类的内容:

public class MainActivity extends AppCompatActivity {
    private final lengthOfFileLatch = new CountDownLatch(1);
    private int lenghtOfFile;
}

@Override
protected void onPostExecute(Integer lenghtOfFile) {
    MainActivity.this.lengthOfFile = lengthOfFile;
    lengthOfFileLatch.countDown();
}

new GetSizeOfFile().execute(stringUrl);
lengthOfFileLatch.await(5, TimeUnit.SECONDS);
Log.i("====", "size of file after Thread: " + lenghtOfFile);`

如果在5秒内没有触发闩锁,你仍然会得到零。否则你会永远阻止(这也可能没有任何参数)。