我有几个相当大的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]);
}
}
}
答案 0 :(得分:1)
是的,这是可能的。
你可以阅读问题和答案 What is the best way for AsyncTask to notify parent Activity about completion
您可以使用委托作为回调函数。
在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);
您的活动,在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
}