HOMEに戻る(ブログのみを御覧の方専用)
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30

カテゴリ:Androidアプリ開発( 2 )
[Android]Android 4.0での通信処理とスレッド
激動のAndroidですが、今からアプリ開発を始めるなら、Android 4.0からをターゲットとするのが良いのではないでしょうか。

と思って、Android 2.2用に書いてたプログラムを、4.0用に移植したんですよ。
そしたら、エラーが出るわ出るわ…。

今回バグを取った中でメモしておきたいと思ったのは次の二つ。

1. 通信処理を行うとNetworkOnMainThreadException発生
2. マルチスレッドにしてUI操作を行う際に「Handler」を使う


1. 通信処理を行うとNetworkOnMainThreadException発生
これは2.2まではうまく行っていましたが、4.0で発生しました。
原因はRainbowDevilsLandさんに書いてあります。

Android3.0からメインスレッド(UIスレッド)から通信を行うとNetworkOnMainThreadExceptionが発生するようになったようだ。



とのことです。
なので、新しくスレッドを起こして、そこで通信処理する必要があります。


2. マルチスレッドにしてUI操作を行う際に「Handler」を使う
で、マルチスレッドにして通信処理させて。
処理が終わると同時にダイアログを出してUIを更新するプログラムにしていましたが、ここで例外発生。
どうやら、UI処理をメインスレッドからサブスレッドに持ってきたのが原因のようです。

これについてはthrow Life - AndroidのHandlerとは何か?さんの説明がわかりやすかったです。
要点としてまとめられている以下を読めば、何がいけなくてどうしなきゃいけないかが見えてきます。

・AndroidのUI操作はシングル・スレッド モデル
・ユーザビリティ向上の為にはマルチスレッドが必要
・Handlerで実現
・Handlerを使わない場合に起きる例外は実行スレッドのチェックで発生
・Handlerを使うと、UI Threadの持つキューにジョブを登録できる
・キューはUI Threadにより実行される
・別スレッドからUI Threadに処理を登録するのでスレッドチェックで例外が発生しない


後は上記サイトのサンプルを見れば、なるほど!と。
[PR]
by icemintken | 2012-02-02 23:28 | Androidアプリ開発
[Android]TwitterアプリのようにListViewで表示する方法
Androidのアプリで、メイン画面からボタンクリック→以下のようなリストを表示する方法について、自分用のメモです。



Androidのことを何もわかっていなかったので、当初「TableLayoutを使えばうまく行くんじゃないの?」と思っていましたが、
Tableではこのように綺麗に表示することは難しく、またリスト内の各セルをクリックすることもできません。
セルをクリックしてアクションを起こしたいことが多いため、これは用途にそぐいません。

ここで知ったのが、ListViewという存在。
これを使用することで上記のようにリスト化でき、またsetOnItemClickListener()というメソッドを使用することでセルクリック時の動作を定義できます。
※ちなみにセル内にImageButtonは配置できません。レイアウトのxmlファイルにImageButtonを誤って配置していてハマりました。
 画像を表示する場合は普通にImageViewで表示します。

<参考>
ListViewを拡張する方法 | public static void main
↑リスト表示の基本的な構成、必要なファイルがわかる。
6. リストとダイアログ | Tuyano's Website
↑リスト表示の基礎。OnItemClickListenerについて補足。
[Android Dev] 拡張ListViewとOnItemClickListener | Moyathinote
↑OnItemClickListenerについて具体例を用いて解説されていて、セルクリック時の動作を定義できます。
Adapter#getViewの挙動について | hyoromoの日記
↑AdapterのgetView()メソッドの挙動について。


まず、MainActivityからボタンクリックで呼び出される新たなActivityを定義します。
その際AndroidManifest.xmlに忘れず記載すること。
今回ぼくはTwitterのとあるツイートを一覧表示したかったので、以下のクラス名にしました。

public class TweetActivity extends Activity

以下、TweetActivity内でのListView作成からAdapterをセットし、レイアウトをセットするところまでです。

/*************************************************/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

LinearLayout lLayout = new LinearLayout(this);//リスト表示用レイアウト作成

ListView lv = new ListView(this);//ListView作成
adapter = new TweetAdapter(this, ListViewのLayout,ArrayListのインスタンス);//自作AdapterにListViewの中身を渡す。
//ArrayListのインスタンスには、リストに表示させるインスタンスを入れる
lv.setAdapter(adapter);
...
(省略)
...
//ListViewのクリック設定
lv.setOnItemClickListener(new OnItemClickListener () {
public void onItemClick(AdapterView parent,
View view, int position, long id) {
......
}
});
...
(省略)
...
//レイアウトにListViewをセット。
lLayout.addView(lv, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT));
setContentView(lLayout);//thisレイアウトにリスト表示用レイアウト設定
/*************************************************/



以下、上記に登場したTweetAdapterクラス。
ArrayAdapterをextendsすると、1画面表示するごとに呼び出されるgetView()メソッドをオーバーライドする必要があります。
このgetView()内で、各セルに表示させたい内容を定義します。
定義するためにはレイアウトが必要で、各セルに適したレイアウトを用意する必要があります。
public class TweetAdapter extends ArrayAdapter


以下、コンストラクタ。
/*************************************************/
private LayoutInflater layoutInflater = null;
private ArrayList listTweet = null;

public TweetAdapter(Context context, int textViewResourceId,
ArrayList tweets) {
super(context, textViewResourceId, tweets);

//layoutInflaterを取得
layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);//このlayoutInflaterを使用してレイアウトを設定する
listTweet = tweets;//TweetAdapter生成時に渡されるArrayListのインスタンスがここに入る
}
/*************************************************/

以下、getView()メソッドと、レイアウトの設定の仕方
/*************************************************/
@Override
public View getView(int position, View convertView, ViewGroup parent) {

//if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.tweetlist, null);//R.layout.tweetlistというレイアウトファイルを読込んで新規レイアウト定義
//}
/*************************************************/
getView()についてはAdapter#getViewの挙動について | hyoromoの日記がわかりやすいです。
1画面のViewがconvertViewに含まれるので、convertViewを再利用する場合は、これがnullかそうじゃないかで処理を分ければ良いです。
でもぼくはハマって、セルの同じ内容がループして表示されてしまったので、とりあえずconvertViewについて気にしないようにしました。

ちなみにpositionには、セルの行数が入ります。」
最後のセルだけ異なるレイアウトにしたい場合は、このpositionがラストセルだった場合に新たなレイアウトファイルをconvertViewに読込ませれば良いです。


/*************************************************/
レイアウト内のリソース定義
ImageView imageView = (ImageView) convertView.findViewById(R.id.tweetButton);
TextView tweetText = (TextView) convertView.findViewById(R.id.tweetText);

tweetText.setText("xxxx");

return convertView;
/*************************************************/



以下、読込んだR.layout.tweetlist
/*************************************************/
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tweetlistlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<ImageView
android:id="@+id/tweetButton"
android:layout_width="50px"
android:layout_height="50px"
android:src="@drawable/icon01"
/>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tweetText"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="16sp"
android:layout_x="150px"
android:layout_y="0px"
/>
</LinearLayout>
/*************************************************/
[PR]
by icemintken | 2011-07-19 00:02 | Androidアプリ開発


その他のジャンル

ファン

記事ランキング

ブログジャンル

画像一覧