Java 使用在其外部线程中更新的arrayList值
基本上,我在一个线程中从一个网站获取一些链接,并将其添加到ArrayList中。 但是当我检查ArrayList的大小时,它返回0。是否有任何方法可以使其中的新值反映出线程之外的值 代码如下:Java 使用在其外部线程中更新的arrayList值,java,android,multithreading,Java,Android,Multithreading,基本上,我在一个线程中从一个网站获取一些链接,并将其添加到ArrayList中。 但是当我检查ArrayList的大小时,它返回0。是否有任何方法可以使其中的新值反映出线程之外的值 代码如下: lsiter.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, Vie
lsiter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final ArrayList<String>LinkAr = new ArrayList<String>();
new Thread(new Runnable() {
@Override
public void run() {
Document doc = null;
try {
doc = Jsoup.connect(message).get();
} catch (IOException e) {
e.printStackTrace();
}
//Title
Element TitleSpan = doc.select("span.detail-info-right-title-font").first();
String TitleString = TitleSpan.text();
//Chaps Names
Elements Chaps = doc.getElementsByClass("title3");
for(Element item: Chaps){
LinkAr.add(item.text());
}
}
}).start();
int pos = parent.getPositionForView(view);
String ClickedVal = (String) parent.getItemAtPosition(position);
Toast.makeText(ChapterPage.this, LinkAr.size() + "@ " + ClickedVal, Toast.LENGTH_SHORT).show();
}
});
lsiter.setOnItemClickListener(新的AdapterView.OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父对象、视图、整型位置、长id){
final ArrayListLinkAr=新的ArrayList();
新线程(newrunnable()){
@凌驾
公开募捐{
单据单据=空;
试一试{
doc=Jsoup.connect(message.get();
}捕获(IOE异常){
e、 printStackTrace();
}
//头衔
元素标题span=doc.select(“span.detail-info-right-title-font”).first();
字符串TitleString=TitleSpan.text();
//查普斯的名字
元素Chaps=doc.getElementsByClass(“标题3”);
用于(元素项:Chaps){
LinkAr.add(item.text());
}
}
}).start();
int pos=parent.getPositionForView(视图);
字符串ClickedVal=(字符串)parent.getItemAtPosition(位置);
Toast.makeText(ChapterPage.this,LinkAr.size()+“@”+ClickedVal,Toast.LENGTH_SHORT).show();
}
});
警告:我不懂安卓。我在这里说的是Java
警告:正如其他人所评论的,你的应用程序在后台线程上执行特定的工作负载可能有意义,也可能没有意义。我将忽略这个问题,重点回答如何在后台线程上生成数据。这取决于读者决定这样做是否适合他们的特定应用程序
在Java中,我们不再需要手动管理线程。Executors框架()内置于Java5中,用于将应用程序开发人员从复杂的线程处理工作中解放出来
ExecutorService
作为全局变量
建立由线程池支持的executor服务。在应用程序中的某个位置保留对executor服务的引用。此executor服务将重复使用
要配置ExecutorService
对象,请使用类中的工厂方法
在您的onItemClick中输入代码
在onItemClick
方法中,将要完成的工作定义为可调用的
。Callable
返回一个值。在本例中,您希望返回URL的列表
或集
。后台线程无需访问onItemClick
代码中的列表。只需让后台线程生成一个新的列表或集合,并将该列表/集合返回给调用代码。更干净的分离
显然,您正在使用String
对象来表示URL。但我们有一个这样的课程:。让我们生成一个URL
对象列表,指定为list
。我们期望我们的可调用对象最终生成并返回列表
。如果任务出现问题,我们希望可调用的
返回一个空列表,而不是抛出异常(如果这适合您的业务逻辑)
稍后,只要您愿意,就可以检查任务的状态。未来
可能会报告任务已完成或已取消。否则,我们可以假设任务不完整,仍在继续
如果Future
报告为已完成,我们可以检索其结果。这里是一个列表
对象
// … check to see if the URL fetch work has been done yet.
if ( futureUrls.isDone() )
{
List < URL > urls = futureUrls.get();
// … Use your list of URLs.
} else if ( futureUrls.isCancelled() )
{
// … deal with cancellation.
} // else neither done nor cancelled, so still being worked. Check back again later.
/…检查URL获取工作是否已完成。
if(futureURL.isDone())
{
ListURL=futureURL.get();
//…使用您的URL列表。
}else if(futureURL.isCancelled())
{
//…处理取消。
}//否则既没有完成也没有取消,因此仍在工作。请稍后再试。
上面的语法不完整。我们必须找出某些例外情况。让我们添加try-catch
// … check to see if the URL fetch work has been done yet.
if ( futureUrls.isDone() )
{
try
{
List < URL > urls = futureUrls.get();
// …Use your URL collection…
}
catch ( InterruptedException e )
{
e.printStackTrace();
}
catch ( ExecutionException e )
{
e.printStackTrace();
}
} else if ( futureUrls.isCancelled() )
{
// … deal with cancellation.
} // else neither done nor cancelled, so still being worked. Check back again later.
/…检查URL获取工作是否已完成。
if(futureURL.isDone())
{
尝试
{
ListURL=futureURL.get();
//…使用您的URL集合…
}
捕捉(中断异常e)
{
e、 printStackTrace();
}
捕获(执行例外)
{
e、 printStackTrace();
}
}else if(futureURL.isCancelled())
{
//…处理取消。
}//否则既没有完成也没有取消,因此仍在工作。请稍后再试。
等待任务完成
如果希望调用线程无限期地等待任务完成,请调用。但是,避免在主用户界面线程中执行此操作,因为您的应用程序对用户没有响应,似乎已冻结/崩溃
如果希望调用线程短暂等待任务完成,请在传递等待时间的同时调用。当等待时间到期且任务仍未完成时,调用线程将继续执行其他工作。同样,不要在UI线程中等待太长时间,因为UI会冻结那么长的时间
不要弄乱用户界面
重要提示:切勿从后台线程访问用户界面。坏事可能发生,也可能不会发生
清理
最后,请确保在应用程序结束之前,优雅地关闭executor服务。否则,它的线程备份池可能会无限期地继续。您启动了一个线程来构建列表,但没有等待它完成。如果在启动线程后立即需要线程的结果,那么首先创建线程是没有意义的,逻辑是连续的
Future < List < URL > > futureUrls = executorService.submit( urlFetch );
// … do other work while you wait.
// … check to see if the URL fetch work has been done yet.
if ( futureUrls.isDone() )
{
List < URL > urls = futureUrls.get();
// … Use your list of URLs.
} else if ( futureUrls.isCancelled() )
{
// … deal with cancellation.
} // else neither done nor cancelled, so still being worked. Check back again later.
// … check to see if the URL fetch work has been done yet.
if ( futureUrls.isDone() )
{
try
{
List < URL > urls = futureUrls.get();
// …Use your URL collection…
}
catch ( InterruptedException e )
{
e.printStackTrace();
}
catch ( ExecutionException e )
{
e.printStackTrace();
}
} else if ( futureUrls.isCancelled() )
{
// … deal with cancellation.
} // else neither done nor cancelled, so still being worked. Check back again later.