重い処理をAsyncTaskを使って別スレッドとして処理する方法

UIスレッドで重たい処理を実行すると画面がフリーズした状態になります。
重い処理は、UIスレッドで実行するのではなく、AsyncTaskを使って別スレッドで実行した方がユーザに違和感を与えません。
AsyncTaskは、実行したい処理の前処理と後処理も簡単に実装できる優れものです。
以下の使用例では、AsyncTaskを承継した内部クラスを定義し、前処理としてプログレスDialogを表示する処理、後処理としてプログレスDialogを閉じる処理を記述しています。ちなみに、AsyncTaskを使わないでプログレスDialogを表示しようとしても、重い処理のためUIスレッドが更新されず、うまく表示されません。

public class BackgroundTask extends AsyncTask<Void,Integer,Boolean>
{
	private Context context = null;
	private ProgressDialog dialog = null;
	private String title;
	private String msg;
	//コンストラクタ
	public BackgroundTask(Context context,String title,String msg)
	{
		this.context = context;
		this.title = title;
		this.msg = msg;
	}
	//処理実行前メソッド
	protected void onPreExecute()
	{
		//プログレスダイアログ設定
		dialog = new ProgressDialog(context);
		dialog.setIndeterminate(true);
		dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		dialog.setTitle(title);
		dialog.setMessage(msg);
		dialog.show();
	} 
	//処理実行中メソッド
	protected Boolean doInBackground(Void... params)
	{
		//ここに重い処理を記述
		return true;
	}
	//処理実行後メソッド
	protected void onPostExecute(Boolean result)
	{
		//プログレスダイアログ消去
		dialog.dismiss();
	}
}

実行は、インスタンス生成後にexecuteメソッドを呼び出せばOKです。

BackgroundTask task = new BackgroundTask(this,"データ処理中","しばらくお待ち下さい♪");
task.execute();

ダイアログにXMLレイアウトを設定する方法

ダイアログでXMLレイアウトを表示する場合は、以下のようにLayoutInflaterでViewを生成してsetViewメソッドにて設定します。

//コンテキストからインフレータを取得
LayoutInflater inflater = LayoutInflater.from(this);
//レイアウトXMLからビュー(レイアウト)をインフレート
final View updateView = inflater.inflate(R.layout.a1_update,null);
//ダイアログ設定
AlertDialog.Builder ad = new AlertDialog.Builder(this);
ad.setIcon(R.drawable.icon);
ad.setTitle("タイトル");
ad.setView(updateView);
updateCategory = (EditText)updateView.findViewById(R.id.update_category);
updateCategory.setText(category[i],EditText.BufferType.NORMAL);
ad.setMessage("メッセージ");
ad.setPositiveButton("OK",new DialogInterface.OnClickListener()
{
	public void onClick(DialogInterface di,int which_button)
	{
		//OKボタン処理
	}
});
ad.setNegativeButton("NG",new DialogInterface.OnClickListener()
{
	public void onClick(DialogInterface di,int which_button)
	{
		//NGボタン処理
	}
});
ad.create();
ad.show();

リソースIDを文字列から生成する方法

大量の画像データ(例えばm0.png〜m99.png)をリソースから取得する場合、以下のように全て記述するのは非効率的です。

mBitmap[0] = BitmapFactory.decodeResource(getResources(),R.drawable.m0);
mBitmap[1] = BitmapFactory.decodeResource(getResources(),R.drawable.m1);
mBitmap[2] = BitmapFactory.decodeResource(getResources(),R.drawable.m2);
mBitmap[3] = BitmapFactory.decodeResource(getResources(),R.drawable.m3);
・
・
・
mBitmap[99] = BitmapFactory.decodeResource(getResources(),R.drawable.m99);

こんなときは、リソースIDを文字列から生成すればソースがスッキリします。

for(int i=0;i<100;i++){
	int resId = getResources().getIdentifier("m"+String.valueOf(i),"drawable",this.getPackageName());
	mBitmap[i] = BitmapFactory.decodeResource(getResources(),resId);
}

レイアウトからfindViewById()で大量のButtonを取得したい等汎用的に使えるテクニックです。
これは便利。

フルスクリーン表示の設定方法

フルスクリーン表示する場合は、Activity内で以下を宣言します。なお、setContentView()よりも前に記述する必要があります。

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

リソースファイルでサイズを定義する方法

リソースファイルでフォントサイズ等を定義して利用する場合は、以下のように記述します。

font_size = getResources().getDimension(R.dimen.font_small_sp);

リソースファイル「dimens.xml」では、以下のように定義します。

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<dimen name="margin_small_dp">3dp</dimen>
	<dimen name="margin_medium_dp">5dp</dimen>
	<dimen name="margin_large_dp">7dp</dimen>
	<dimen name="font_small_sp">13sp</dimen>
	<dimen name="font_medium_sp">15sp</dimen>
	<dimen name="font_large_sp">17sp</dimen>
</resources>

なお、dpとspは、画面解像度に依存しない単位です。
画面解像度に応じて拡大縮小されますので、これらの単位を使用すれば、様々な解像度にアプリを対応させることができます。
フォントサイズにはsp、それ以外のサイズにはdpを使用します。

ldpi--> 1dp/1sp = 0.75px
mdpi--> 1dp/1sp = 1.0px
hdpi--> 1dp/1sp = 1.5px

と解像度に応じて拡大縮小して表示されます。