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

标签 java android

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

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

代码:

公共(public)类 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]);
    }       
}

最佳答案

是的,这是可能的。

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

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

第一步:“回调函数”

LoadFilesTask中创建一个接口(interface),

public interface AsyncResponse {
    void processFinish(String[][] types, String[][] moves, String[][] dex);
}
public AsyncResponse delegate = null;

并创建一个公共(public)构造函数来强制任何想要使用 LoadFilesTask 的人将 processFinish 传递给它。

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

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

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

第 2 步:实现回调函数

在 UI 线程上运行的 Activity :

变量:

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 


}

关于java - 任务完成后是否可以保留 Asynctask 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34356066/

相关文章:

android - cordova 构建 android 在 :app:mergeReleaseResources step with "Daemon startup failed" message 上失败

Android nfcA.connect()、nfcA.transceive()、nfcA.setTimeout() 和 nfcA.getMaxTransceiveLength()

android - 在 RadioButton 中使用图像而不是文本

java - 将整数放入 xpath 的引号中

javax.xml.bind.UnmarshalException : unexpected element. 预期的元素是(无)

java - HttpClient执行时出现org.apache.http.client.ClientProtocolException

java - Android 加载时的多个 Web 服务调用

java - 客户端-服务器应用程序。总是打开套接字

java - 在几个不同的参数内生成随机数

java - Testng 报告头等舱 2 个类(class)的所有测试