AsyncTaskLoaderの使い方
AsyncTaskが非推奨ということでAsyncTaskLoaderを使ってみたんだけど使いにくいということで解説
今回はネットから何か拾ってくることを想定して書いてみました。
まず起動する側(ActivityやFragmentから)に書かないといけないこと
public class MainActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<String>, View.OnClickListener {
public static String KEY = "key";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle bundle=new Bundle();
bundle.putString(KEY,/* 取得したいページ */);
//SupportLibrary使ってない場合はgetLoaderManager().initLoader(0,bundle,this);
getSupportLoaderManager().initLoader(0,bundle,this);
}
@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
Log.d("onCreateLoader","onCreateLoader");
URL url = null;
try {
url=new URL(/* urlの内容 */);
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
MyAsyncTaskLoader loader= new MyAsyncTaskLoader(this,url);
//loader.startLoading();
return loader;
}
@Override
public void onLoadFinished(Loader<String> loader, String data) {
Log.d("onLoadFinished",data);
//ここでdataをつかう
}
@Override
public void onLoaderReset(Loader<String> loader) {
}
}AsyncTaskLoaderの起動は
getLoaderManager().initLoader(0,bundle,this);
で行って
onCreateLoader
でLoaderの作成して返してLoaderが動き出す。結果を
onLoadFinished
で受け取るのが基本的な構造
AsyncTaskLoader側は
public class MyAsyncTaskLoader extends android.support.v4.content.AsyncTaskLoader<String> {
URL mUrl;
String mHtml;
public MyAsyncTaskLoader(Context context, URL url) {
super(context);
mUrl = url;
}
@Override
protected void onStartLoading() {
if (mHtml != null) {
//利用可能な場合は、すぐに結果を返す。
deliverResult(mHtml);
}
if (takeContentChanged() || mHtml == null) {
forceLoad();
}
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override
public void deliverResult(String data) {
if (isReset()) {
if (mHtml != null) {
// ローダが停止している間の非同期クエリが入って来ました。我々は結果を必要としません。
onReleaseResources(mHtml);
}
}
String oldHtml = mHtml;
mHtml = data;
if (isStarted()) {
// ローダーが現在起動している場合、我々はすぐにその結果を提供することができます。
super.deliverResult(data);
}
if (oldHtml != null) {
onReleaseResources(oldHtml);
}
}
@Override
public void onCanceled(String data) {
super.onCanceled(data);
// この時点では、必要に応じて「アプリ」に関連したリソースを解放することができます。
onReleaseResources(data);
}
@Override
protected void onReset() {
super.onReset();
// ローダが停止されていることを確認します。
onStopLoading();
// この時点では、必要に応じて「アプリ」に関連したリソースを解放することができます。
if (mHtml != null) {
onReleaseResources(mHtml);
mHtml = null;
}
}
@Override
public String loadInBackground() {
StringBuilder stringBuffer = new StringBuilder();
try {
HttpURLConnection httpURLConnection = (HttpURLConnection) mUrl.openConnection();
httpURLConnection.setConnectTimeout(10 * 1000);
httpURLConnection.setReadTimeout(30 * 1000);
httpURLConnection.setRequestMethod("GET");
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line).append("\n");
}
bufferedReader.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
mHtml = stringBuffer.toString();
return mHtml;
}
/**
* Helper function to take care of releasing resources associated
* with an actively loaded data set.
*/
protected void onReleaseResources(String apps) {
// For a simple List<> there is nothing to do. For something
// like a Cursor, we would close it here.
}
}
onStartLoading
が最初に実行されてその中の
forceLoad()
が実行されると
loadInBackground()
の中が実行される
このloadInBackground()の中に大体やりたい事(今回はネットから拾ってくる)をする
loadInBackground()の返り値が
deliverResult()
を通ってActivityまたはFragment側のonLoadFinishedに渡る