AsyncTaskLoaderの使い方 :Android

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に渡る

スポンサーリンク

シェアする

フォローする

スポンサーリンク