任务完成后是否可以保留Asynctask变量?

时间:2015-12-18 12:47:14

标签: java android

我有几个相当大的csv文件,我希望导入并存储为变量因此,我使用asyncTask打开并存储所有数据。 (我知道这可以使用数据库完成,但我希望它可以离线运行,这就是我选择这条路径的原因。)

我认为当任务完成时会删除局部变量及其数据,因此我尝试将变量全局存储在' (不确定Java术语,但基本上变量可以被该类中的所有函数访问)。现在,数据存储在一个二维数组中,而我在 doInBackground 函数(asyncTask)中我可以打印数组中的值就好了,但是,一旦完成任务完成后我再也无法访问它了。没有错误信息出现在应用程序崩溃。

代码:

public class Main extends Activity实现OnClickListener {

String[][] types = new String[19][2];
String[][] moves = new String[619][9];
String[][] dex = new String[785][6];

private class LoadFilesTask extends AsyncTask<Void, Void, Void> {

    protected Void doInBackground(Void... params) {

        try {

            CSVReader reader = new CSVReader(new InputStreamReader(getAssets().open("types.csv")));
            List<String[]> list = reader.readAll();
            types = list.toArray(types);

            CSVReader reader_moves = new CSVReader(new InputStreamReader(getAssets().open("moves.csv")));
            List<String[]> list_moves = reader_moves.readAll();
            moves = list_moves.toArray(moves);

            CSVReader reader_pokedex = new CSVReader(new InputStreamReader(getAssets().open("dex.csv")));
            List<String[]> list_dex = reader_pokedex.readAll();
            dex = list_dex.toArray(dex);

            for (int i = 0; i < 19; i++) {
                for (int j = 0; j < 2; j++ )
                    Log.w("app", types[i][j]);
            }

            for (int i = 0; i < 10; i++) {
                for (int j = 0; j < 5; j++ )
                    Log.w("app", dex[i][j]);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }


    protected void onPostExecute(Void result) {
        Log.w("app", "Files Loaded" );

    }

}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    findViewById(R.id.my_button).setOnClickListener(this);
}

@Override
public void onClick(View arg0) {
    Button b = (Button)findViewById(R.id.my_button);
    b.setClickable(false);

    EditText input = (EditText) findViewById(R.id.user_edit);

    InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    mgr.hideSoftInputFromWindow(input.getWindowToken(), 0);


    new LoadFilesTask().execute();

    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 5; j++ )
            Log.w("app", moves[i][j]);
    }       
}

}

1 个答案:

答案 0 :(得分:1)

是的,这是可能的。

你可以阅读问题和答案 What is the best way for AsyncTask to notify parent Activity about completion

您可以使用委托作为回调函数。

第1步:&#34;回调函数&#34;

LoadFilesTask

中创建一个界面
public interface AsyncResponse {
    void processFinish(String[][] types, String[][] moves, String[][] dex);
}
public AsyncResponse delegate = null;

并创建一个公共构造函数,强制任何想要使用LoadFilesTask的人传递processFinish

//constructer
public LoadFilesTask(AsyncResponse delegate){
    this.delegate = delegate;
}

最后,在onPostExecute上调用委托(记得在LoadFilesTask中将三个String数组声明为全局变量,并将它们作为参数传递给delegate.processFinish

@Override
protected void onPostExecute(...) {
    delegate.processFinish(types, moves, dex);

第2步:实施回调功能

您的活动,在UI主题上运行:

变量:

String[][] types = new String[19][2];
String[][] moves = new String[619][9];
String[][] dex = new String[785][6];

实施LoadFilesTask.AsyncResponse

public class YOUACTIVITY OR FRAGMENT extends ... implements LoadFilesTask.AsyncResponse, View.OnClickListener{

@Override
public void processFinish(String[][] types, String[][] moves, String[][] dex) {

    this.types =types;
    this.moves = moves;
    this.dex = dex;

    //Do whatever you want to do in Callback function
    Toast.makeText(context, "Read File Successfully!", Toast.LENGTH_LONG).show();
}

最后,让我们执行新任务:

@Override
public void onClick(View arg0) {

//whatever

    new LoadFilesTask(this).execute();

//whatever 


}