いくつかの長い計算を行うアプリケーションがあり、これが行われている間に進行ダイアログを表示したいと思います。これまでのところ、スレッド/ハンドラーでこれを行うことができることを発見しましたが、動作しませんでした。そして、AsyncTask
について知りました。
私のアプリケーションでは、マーカーが付いたマップを使用し、onTap関数を実装して、定義したメソッドを呼び出しています。このメソッドは、[はい/いいえ]ボタンのあるダイアログを作成します。[はい]をクリックした場合、AsyncTask
を呼び出したいと思います。私の質問は、ArrayList<String>
をAsyncTask
に渡す方法(そこで動作する)、およびAsyncTask
からの結果のような新しいArrayList<String>
を取得する方法ですか?
メソッドのコードは次のようになります。
String curloc = current.toString();
String itemdesc = item.mDescription;
ArrayList<String> passing = new ArrayList<String>();
passing.add(itemdesc);
passing.add(curloc);
ArrayList<String> result = new ArrayList<String>();
new calc_stanica().execute(passing,result);
String minim = result.get(0);
int min = Integer.parseInt(minim);
String glons = result.get(1);
String glats = result.get(2);
double glon = Double.parseDouble(glons);
double glat = Double.parseDouble(glats);
GeoPoint g = new GeoPoint(glon, glat);
String korisni_linii = result.get(3);
したがって、ご覧のとおり、文字列配列リストをAsyncTask
に「渡す」ことで送信し、そこから「結果」文字列配列リストを取得します。そして、calc_stanica AssycTask
クラスは次のようになります。
public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> {
ProgressDialog dialog;
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(baraj_mapa.this);
dialog.setTitle("Calculating...");
dialog.setMessage("Please wait...");
dialog.setIndeterminate(true);
dialog.show();
}
protected ArrayList<String> doInBackground(ArrayList<String>... passing) {
//Some calculations...
return something; //???
}
protected void onPostExecute(Void unused) {
dialog.dismiss();
}
だから私の質問は、AsyncTask doInBackground
メソッドで "passing"配列リストの要素を取得し(そこで使用する)、mainメソッドで使用する配列リストを返す方法( "result"配列)です。リスト)?
メソッドを次のように変更します。
String curloc = current.toString();
String itemdesc = item.mDescription;
ArrayList<String> passing = new ArrayList<String>();
passing.add(itemdesc);
passing.add(curloc);
new calc_stanica().execute(passing); //no need to pass in result list
非同期タスクの実装を変更します
public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> {
ProgressDialog dialog;
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(baraj_mapa.this);
dialog.setTitle("Calculating...");
dialog.setMessage("Please wait...");
dialog.setIndeterminate(true);
dialog.show();
}
protected ArrayList<String> doInBackground(ArrayList<String>... passing) {
ArrayList<String> result = new ArrayList<String>();
ArrayList<String> passed = passing[0]; //get passed arraylist
//Some calculations...
return result; //return result
}
protected void onPostExecute(ArrayList<String> result) {
dialog.dismiss();
String minim = result.get(0);
int min = Integer.parseInt(minim);
String glons = result.get(1);
String glats = result.get(2);
double glon = Double.parseDouble(glons);
double glat = Double.parseDouble(glats);
GeoPoint g = new GeoPoint(glon, glat);
String korisni_linii = result.get(3);
}
UPD:
タスク開始コンテキストにアクセスしたい場合、最も簡単な方法は、onPostExecuteをその場でオーバーライドすることです。
new calc_stanica() {
protected void onPostExecute(ArrayList<String> result) {
// here you have access to the context in which execute was called in first place.
// You'll have to mark all the local variables final though..
}
}.execute(passing);
なぜArrayListを渡すのですか?? paramsを使用してexecuteを直接呼び出すことができるはずです:
String curloc = current.toString();
String itemdesc = item.mDescription;
new calc_stanica().execute(itemdesc, curloc)
Varrargsがどのように機能するのでしょうか? ArrayListを作成して変数を渡すのは二重の作業です。
私はこの点について無駄を省いたことに同意します。
コール:
new calc_stanica().execute(stringList.toArray(new String[stringList.size()]));
仕事:
public class calc_stanica extends AsyncTask<String, Void, ArrayList<String>> {
@Override
protected ArrayList<String> doInBackground(String... args) {
...
}
@Override
protected void onPostExecute(ArrayList<String> result) {
... //do something with the result list here
}
}
または、結果リストをクラスパラメーターにして、ArrayListをブール値(成功/失敗)に置き換えるだけでもかまいません。
public class calc_stanica extends AsyncTask<String, Void, Boolean> {
private List<String> resultList;
@Override
protected boolean doInBackground(String... args) {
...
}
@Override
protected void onPostExecute(boolean success) {
... //if successfull, do something with the result list here
}
}
私はこのようにしないでください。 asychtaskクラスのコンストラクタをオーバーロードする方が簡単だと思います..
パブリッククラスcalc_stanicaはAsyncTaskを拡張します>
String String mWhateveryouwantToPass;
public calc_stanica( String whateveryouwantToPass)
{
this.String mWhateveryouwantToPass = String whateveryouwantToPass;
}
/*Now you can use whateveryouwantToPass in the entire asynchTask ... you could pass in a context to your activity and try that too.*/ ... ...
次のような結果を返すことができます:AsyncTask
class
@Override
protected Boolean doInBackground(Void... params) {
if (Host.isEmpty() || dbName.isEmpty() || user.isEmpty() || pass.isEmpty() || port.isEmpty()) {
try {
throw new SQLException("Database credentials missing");
} catch (SQLException e) {
e.printStackTrace();
}
}
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
this.conn = DriverManager.getConnection(this.Host + ':' + this.port + '/' + this.dbName, this.user, this.pass);
} catch (SQLException e) {
e.printStackTrace();
}
return true;
}
受信クラス:
_store.execute();
boolean result =_store.get();
それが役立つことを願っています。