如何检查线程是否已完成执行Android Studio

如何检查线程是否已完成执行Android Studio,android,multithreading,Android,Multithreading,我正在尝试创建一个包含两个微调器的应用程序,其中包含来自数据库的数据。按下按钮时,将创建一个新的意图,显示2个微调器。问题是我必须在一个新线程中创建DB查询,当我运行应用程序时,我得到一个空指针异常(据我所知,这是因为我存储DB数据的数组尚未填充)。 我的问题是,如何延迟微调器的创建,直到DB发出查询为止? 下面是我的实现的示例代码: 创建微调器并调用进行DB查询的类的目的是: String [][] dbData; //the array where i store data from DB

我正在尝试创建一个包含两个微调器的应用程序,其中包含来自数据库的数据。按下按钮时,将创建一个新的意图,显示2个微调器。问题是我必须在一个新线程中创建DB查询,当我运行应用程序时,我得到一个空指针异常(据我所知,这是因为我存储DB数据的数组尚未填充)。 我的问题是,如何延迟微调器的创建,直到DB发出查询为止? 下面是我的实现的示例代码: 创建微调器并调用进行DB查询的类的目的是:

String [][] dbData; //the array where i store data from DB
getDBdata myData = new getDBdata(); // create a new instance of the class that queries the DB
dbData = myData.getData(); // I get the data
Log.e("My log: ", String.valueOf(dbData.length)); //and here it crashes, giving me a null pointer exception
以及我在其中创建新线程以进行DB查询的类:

public getDBdata()
{
    Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            DBconn(); //make a DB query 
        }
    });
    thread.start();
}
public String[][] getData()
{
    return data;
}

最简单的方法是使用。
AsyncTask
的基本思想是将任务的执行分为三个步骤,然后依次执行。每个步骤都在一个单独的线程中运行。最后一个在主(UI)中运行,您可以在其中创建微调器。样本:

public class DBQueryTask extends AsyncTask<Void, Void, String[][]> {

    @Override
    protected String[][] doInBackground(Void... params) {
        DBconn();
        String[][] a;
        //...populating array
        return a;//returning populated array
    }

    @Override
    protected void onPostExecute(String[][] strings) {
        //strings - array already populated
        //this method runs on the Main thread. Therefore you can create your spinner
    }
}
公共类DBQueryTask扩展异步任务{
@凌驾
受保护的字符串[][]doInBackground(Void…params){
DBconn();
字符串[][]a;
//…填充数组
返回;//返回填充的数组
}
@凌驾
受保护的void onPostExecute(字符串[][]字符串){
//字符串-数组已填充
//此方法在主线程上运行。因此,您可以创建微调器
}
}

如果要等待线程完成,则不需要新线程。但是如果您这样做了,那么您不需要等待它完成,而是使用回调方法

private static final int MESSAGE_DATA_RETRIEVED = 1;

private String [][] dbData; //the array where i store data from DB

private Handler mHandler;

// in onCreate or constructor depending what are you in

mHandler = new DataHandler(this);

// end of onCreate or constructor

private void getData() {
    final getDBdata myData = new getDBdata(mHandler);
    myData.getData();
}

private void onDataRetrieved() {
    Log.e("My log: ", String.valueOf(dbData.length));
}

private static final class DataHandler extends Handler {

    private final WeakReference<YourEnclosingClass> mClassReference;

    DataHandler(final YourEnclosingClass instance) {
        mClassReference = new WeakReference<>(instance);
    }

    @Override
    public void handleMessage(Message msg) {
        if (msg.what == MESSAGE_DATA_RETRIEVED) {
            final YourEnclosingClass instance = mClassReference.get();
            if (instance != null) {
                instance.onDataRetrieved();
            }
        }
    }

}
多线程就是这样完成的


但无论如何,这是个坏主意。您必须使用AsyncTask或CursorLoader来执行任务。

干杯,这正是我想要的!
private final Handler mHandler;

// calling a class a verb is bad. Should be a noun, but I haven't took a time to rename it here
public getDBdata(final final Handler handler) {
    mHandler = handler;
    // starting a Thread in constructor is a bad idea. I moved it to a method
}

public void getData()
{
    final Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            DBconn(); //make a DB query 
            nHandler.sendEmptyMessage(MESSAGE_DATA_RETRIEVED);
        }
    });
    thread.start();
}