Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/179.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用在其外部线程中更新的arrayList值_Java_Android_Multithreading - Fatal编程技术网

Java 使用在其外部线程中更新的arrayList值

Java 使用在其外部线程中更新的arrayList值,java,android,multithreading,Java,Android,Multithreading,基本上,我在一个线程中从一个网站获取一些链接,并将其添加到ArrayList中。 但是当我检查ArrayList的大小时,它返回0。是否有任何方法可以使其中的新值反映出线程之外的值 代码如下: lsiter.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, Vie

基本上,我在一个线程中从一个网站获取一些链接,并将其添加到ArrayList中。 但是当我检查ArrayList的大小时,它返回0。是否有任何方法可以使其中的新值反映出线程之外的值

代码如下:

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.