我有几个相当大的 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/