繁体   English   中英

在 Android 应用程序中使用线程

[英]Using Threads in an Android app

在我的 android 应用程序中,我有一个 Activity 和多个 java class 这不是一个活动。 所以在这个其他的java class中有一个get方法,它返回一个Object。 此方法启动一个新线程来获取数据并将其附加到 object

现在我在我的 Activity 中调用这个 get 方法来获取 object。 我正在做这样的事情 -

mNewsList = new ArrayList<NewsContentManager.NewsPojo>();
mNewsList = manager.getNewsList();

and the method is this -

    public ArrayList<NewsPojo> getNewsList() {
        Log.v("TAG", ""+newsList);
        if(newsList == null)
        {
            Thread t = new Thread(){
                public void run(){

                    Log.v("TAG", "Inside run");

                    np1 = new NewsPojo();
                    np1.setTitle("A");
                    np1.setDescription("dhghfdklsa");


                    np2 = new NewsPojo();
                    np2.setTitle("B");
                    np2.setDescription("dhghfdklsa");


                    np3 = new NewsPojo();
                    np3.setTitle("c");
                    np3.setDescription("dhghfdklsa");

                    newsList = new ArrayList<NewsPojo>();

                    Log.v("in run",""+newsList);

                    newsList.add(np1);
                    newsList.add(np2);
                    newsList.add(np3);

                    Log.v("in run",""+newsList.size());

                    setNewsList(newsList);

                    handler.sendEmptyMessage(0);

                }// end of run
            };// end of thread
            t.start();
        }//end of if

        return newsList;
    }

但是我在我的活动中遇到了 nullPointer 异常。 如果我从此方法中删除 Thread ,那么它可以正常工作。 我应该怎么办?

谢谢

因为您的线程完成工作的时间比预期的要晚。 你应该同步线程和ui线程。
看看 Android 的AsyncTask

该方法将始终返回null ,因为newsList在您返回会被初始化。 所以mNewsList将是null并且不会被线程更新(它将更新newsList但不会更新mNewsList )。

对于测试/演示:在您的 return 语句之前添加一个Thread.sleep(500) - 然后它按预期工作。


这是您的问题的快速解决方案:

public ArrayList<NewsPojo> getNewsList() {
    Log.v("TAG", ""+newsList);
    if(newsList == null)
    {
        newsList = new ArrayList<NewsPojo>(); // <-- new statement!
        Thread t = new Thread(){
           // same lines of code EXCEPT "newsList = new ArrayList<NewsPojo>();" !!
        };
        t.start();
    }
    return newsList;
}

但请记住 - newList 将及时创建,但稍后会与主线程并行填充。 当您查看mNewsList时,它可能会显示一个空的或部分填充的列表。 如果您异步执行操作,这是通常的行为。 如果您不希望这样:不要使用线程来创建/填充列表。

除了我对你的问题的评论。

首先,尽量避免以这种方式使用线程。 请改用 AsyncTask。 在它的 preExecute 上向用户显示一些对话框,您正在加载一个列表,在它的 doInBackground 上放置您将返回新列表的逻辑,并在 postExecute 中关闭对话框并继续。

你得到 NullPointerException,因为你在不同的线程中初始化了 newsList:

newsList = new ArrayList<NewsPojo>();

但是这段代码可能在你返回 newsList 之后执行,这等于 null

    if(newsList == null)
    {
        Thread t = new Thread(){
                ....
        };// end of thread
        t.start(); // << this only starts thread and continues executing
    }//end of if

    return newsList; // this is executed before newsList is initialized in t.run()

如果您必须在 AsyncTask 完成作业之前终止 Activity,您可以使用以下方法在另一个 Activity 中恢复它:

  1. class 代码: private class DownloadImageTask extends AsyncTask {.... }

  2. class 的实例:

     dtdodo = new DownloadImageTask( this, p, codacaovalue); dtdodo.execute("wwwkjhdijdh");
  3. 杀死 Activity(像旋转屏幕这样的事件)。

  4. 恢复 AsyncTask:


   onCreate(){
        Object retained = getLastNonConfigurationInstance();
        if ( retained instanceof DownloadImageTask ) {
                dtdodo = (DownloadImageTask) retained;
                dtdodo.setActivity(this);
        } else {
                dtdodo = new DownloadImageTask(this , 1 , codacaovalue);
                dtdodo.execute();
        }
}

我在一个匿名人的博客中发现了这个,我只是分享。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM