我是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);
答案 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 PropertyChangeEvent
,tutorial 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秒内没有触发闩锁,你仍然会得到零。否则你会永远阻止(这也可能没有任何参数)。