mikebai.com

  • Home
  • dev
  • DotNET
  • M365
  • 搞笑
  • 杂七杂八
  • FocusDict
dev
dev

AdMob相关知识(日文版本)

AdMobへの登録方法 まずは、AdMobのサイトへ行きます。AdMob 「今すぐスタート」というボタンがあるので、それをクリックします。すると、あなたの情報を登録する画面が表示されます。メールアドレス、パスワード、お名前、住所などを入力して、「同意します」のチェックを入れて「Submit」ボタンを押すだけです。AdMobのサービス使用条件とプライバシーポリシーは、英語で書かれてるんですよね…。一応、目は通しておいた方がいいと思います。私はあまり気にしませんでしたが。 クリック報酬型なので、Google Adsenseと同じような規約なのかなと思いますが、特に気をつけておいた方がいいのは、以下のような内容です。・自分でクリックしない。・人に頼んでクリックさせない。・クリックはこちら!とか書いて誘導しない。・これはおそらくですが、アダルト系のコンテンツではNGだと思います。私はしません。 すると、登録したメールアドレスに、AdMobからメールが送られてきますので、そのメール内のURLをクリックするだけで、とりあえず本登録は完了です。 PayPalへの登録 AdMobの広告収入の報酬受取りには、「小切手」か「PayPal」、どちらかしか選択できません。これがちょっとメンドクサイですね。どちらがいいかは、個人の自由ですが、「小切手」は、換金時に手数料が余計に掛かるというイメージ(思い込みかもしれません。)があったので、私は「PayPal」にしました。PayPalのアカウントをお持ちでない方は、PayPalへの登録も必要になります。 PayPalとは、世界中で使われているオンライン決済システムで、ネットバンクみたいなもんです。PayPalのサイトは下記です。PayPalのサイト「新規登録」というリンクがあるので、そこから登録が出来ます。「パーソナル」「ビジネス」「プレミア」とありますが、とりあえず私は個人で登録したかったので、「パーソナル」にしました。会社名義であれば「ビジネス」とするんでしょうね。PayPalへの登録時も、メールアドレス、住所、名前等を入力するだけで、すぐにアカウントが作れます。(クレジットカード番号を登録する事もできるんですが、私は登録していません。) AdMobの支払い情報の設定 それでは次は、AdMobの報酬をどうやって受け取るのかを設定します。AdMobへログインして、「アカウント」->「支払い情報」を選択してください。この画面で、報酬の受取方法を設定します。「国」は「日本」ですね。あなたが日本人なら。「アカウントの種類」は、個人名義でやるのなら「個人」、法人なら「法人」です。「商号」は、個人ならフルネームを、法人なら会社名になるんですかね。もしわからない場合は、AdMobへ聞いてみるといいと思います。 「納税者ID」は、記入不要です。 支払い情報のラジオボタンで、「小切手」か「PayPal」かを選択します。PayPalの場合、入力するのは、PayPalのログイン名だけです。PayPalのログイン名は、PayPalへログインするときに使うメールアドレスでいいです。これはAdMobに直接確認したので、間違い無いです。 以上で、AdMobの初期登録は完了です。あとは、広告を掲載するAndroidアプリケーションを追加していくんですが、AdMobへAndroidアプリを登録する手順は、「AdMobへのAndroidアプリの登録とSDKのダウンロード方法」をご覧下さい。   AdMobへAndroidアプリケーションを登録 まずはAdMobへ、広告を掲載したいAndroidアプリケーションを登録します。AdMobへログインして、「サイト及びアプリケーション」->「サイト/アプリケーションの追加」を選択します。(下図参照) すると、以下のような画面が表示されますので、「Androidアプリケーション」を選択します。 すると、以下のように、Androidアプリの情報を入力する画面が開きます。「App名」にはアプリケーション名を入れます。「AndroidパッケージURL」は、以下のいずれかです。「market://details?id=<packagename>」もしくは 「http://」Androidマーケットに登録しているのであれば、前者の「market://」を、そうでない場合は、単に「http://」とだけ入力すればOKです。私はまだAndroidマーケットに登録してませんので、「market://」の仕様をよく知らないんですが、またわかったら更新しておきます。 「ジャンル」は、選択肢の中から、Androidアプリのジャンルを選択します。「Appの説明」は、そのAndroidアプリの概要を入力します。 各項目の入力が済んだら、「次へ」ボタンを押します。これで、AdMobへのAndroidアプリの登録は一応完了です。以下のような画面が表示されます。 この画面で、AdMob Android SDKのダウンロードと、SDKの説明書がダウンロードできます。「AdMob Android SDKのダウンロード」ボタンを押して、AdMob Android SDKをダウンロードしましょう。内容は、Androidアプリのプロジェクトに組み込む「admob-sdk-android.jar」と、サンプルアプリのプロジェクトと、javadocが格納されています。また、「AdMob Android SDKのダウンロード」ボタンの下にあるPDFファイルのリンクも押して、PDFファイルもついでにダウンロードしておきましょう。説明書もjavadocも英語ですけど・・・。 この画面でダウンロードしておかないと、後でダウンロードできません。いや、出来るんですが、別のAndroidアプリを、これまでの手順をもう一回行って登録して、この画面を表示させないとダウンロードが出来ないんです。なんて不親切な・・・、と思いましたが仕方ありません…。 ちなみに、複数のAndroidアプリを登録する事も当然出来ますが、そのたびに、AdMob Android SDKをダウンロードする必要はありません。どのアプリの登録完了画面でダウンロードしたAdMob Android SDKも、中身は全く同じです。別々のアプリの登録後にダウンロードしたファイルを比較したので、間違いないです。(とあるサイトでは、アプリ毎にSDKの中身が違うと取れる表現もありましたが。) これでAndroidアプリに、AdMob広告を埋め込む前準備はOKです。次回は、実際にAndroidアプリにAdMob広告を埋め込む手順を紹介したいと思います。  

2011-12-05 0comments 99hotness 0likes mikebai Read all
dev

奇怪的String.getBytes("Unicode")

最近在进行联网测试的时候, 客户端:symbian 服务器:java 因为在symbian中,中文是用unicode进行编码的 于是在接收和发送的时候,都必须进行bytes的转换 当我用String.getBytes("Unicode"),进行转换时,总发现客户端发送给服务器的数据总无法被服务器unicode编码 同事服务器发送的数据给客户端,客户端也不能正常的识别 后来当我用String.getBytes("UnicodeBigUnmarked"),数据便一切正常了 于是分析了一下 String temp = "a";         try {             byte[] unicodes = temp.getBytes("Unicode");             System.out.println("unicodes=" + unicodes.length);            for (int i = 0; i < unicodes.length; i++) {                System.out.println(unicodes[i]);            }             unicodes = temp.getBytes("UnicodeLittleUnmarked");            System.out.println("unicodes=" + unicodes.length);            for (int i = 0; i < unicodes.length; i++) {                System.out.println(unicodes[i]);            }                       unicodes = temp.getBytes("UnicodeBigUnmarked");            System.out.println("unicodes=" + unicodes.length);            for (int i = 0; i < unicodes.length; i++) {                System.out.println(unicodes[i]);            }         } catch (UnsupportedEncodingException e) {                       e.printStackTrace();        } 输出结果: unicodes=4-1-2970unicodes=2970unicodes=2097 为什么会有这种结果呢?蓝色的返回了四个字节,-1,-2,是字节顺的一种表示,这是由sun的类库实现, 指示如果没有指定字节就使用默认的UnicodeLittle 但为了标识这种字节顺,就使用了-1,-2在前面表示。 UnicodeLittleUnmarked的结果,其返回字节只是两个字节,这与Unicode的编码相符合,注意到97,0与使用Unicode时后两个字节顺序一样。 UnicodeBigUnmarked的结果,字节顺与Little相反,也没有-1,-2. 由以上应该知道,temp.getBytes("Unicode");应该小心使用,应该注意它返回的-1,-2,这两个字节,因为在一些网络程序中,特别是当对方是由java以外的语言编写,有可能不会使用这种方式来标识字节顺,因此要了解对方的细节,这样才能保证数据的准确传递。

2011-11-16 0comments 92hotness 0likes mikebai Read all
dev

Android 如何设置 Notification 中PendingIntent 的 Intent

已经凌晨了,外面下着该死的雨,把我阻挡在教学楼却不能回寝室(其实主要是我没有可以换的衣服和裤子了,如果冲回去的话...后果可想而知 :)),并且还有那该死的Notification 中 PendingIntent 中的 Intent 却老是配置不好,不过令人欣慰和激动的是我还是搞定了,嘿嘿。废话少说,言归正传。   今天在写完 “ Android Notification 的使用 ” 的时候,发现有几个问题,特别是设置Notification的Intent使之能够像 QQ 或其他程序一样能够正确回调到之前已经放置在后台的Task中的对应Activity,而不是创建它的一个新实例。当然重点便是如何设置该 Activity 的 launchMode 与 Intent 的 Flags 了,说到这里,我不得不说一下今晚的调试经历,当然这里所说的所有的Notification都设置了FLAG_ONGOING_EVENT。   按照 “ (转载)Android下Affinities和Task ”一文所说的,我们不难得出这样的结论:   1、设置当用户触发Notification时所发出的Intent,如果设置 FLAG_ACTIVITY_CLEAR_TOP 与 FLAG_ACTIVITY_NEW_TASK ,而launchMode保持不变(即默认为:standard),则当用户用手点击Notification时,此时匹配到后台的Task,并把在堆栈中对应要启动的Activity之前的所有Activity全部清除掉,并且由于 standard 默认对于新的Intent总是创建新的Activity对象。因此存在于该Task中旧的Activity也会被清除掉,然后在该Task中创建新的 Activity对象。   2、设置当用户触发Notification时所发出的Intent,如果设置 FLAG_ACTIVITY_CLEAR_TOP 与 FLAG_ACTIVITY_NEW_TASK,而launchMode设置为singleTop,则当用户用手点击Notification时,同1一样,只是存在于该Task中旧的Activity不会被清除掉,此时Intent传递给已经存在的Activity并不会创建新的Activity。   上面得出的结论,经过返回测试,1是正确的,2却存在着很莫名奇妙的问题   假设现在有个程序X,有2个Activity,分别是 A , B ,其中 A 是 设置了android.intent.action.MAIN的Activity(入口Activity),两者的launchMode都为默认的 standard,创建该Intent的代码如下:   Intent intent = new Intent(this, A.class);   intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);   很明显我们设置的是当用户点击 Notification 时,应该出现的是 A Activity,但无论如何按home键退出当前Task,并使之成为后台Task,在从程序列表启动该程序总能恢复到Task顶端的Activity 给用户,如 当前 B,按home键,在从程序列表启动 X ,这个时候出现的Activity任然是 B,但按照如下的方法操作却会使得从程序列表启动 X,出现的是新创建的A Activity,其中经过Log打印得知下面的所有Activity都在同一个Task中   1、打开程序出现A,从A startActivity 到B,按Home键,点Notification出现A,再从A startActivity 到 B,按Home键,从程序列表打开程序 出现新创建的实例A   2、打开程序出现A,从A startActivity 到B,点Notification出现A,再从A startActivity 到B,按Home键,从程序列表打开程序也出现了新创建的实例A   这里所说的“新创建的实例A”都是创建在同一Task中的新的A Activity实例,也就是说按照以上两种方法,再按返回键,出现的则是 B,再按返回键出现的则是 A。这里我实在想不出为什么会在同一Task中创建一个新的Activity,就算从程序列表打开程序的Intent使用了 FLAG_ACTIVITY_NEW_TASK标记,我也不知道为什么,如果有朋友知道,一定要告诉我。   到这里,我开始发现 从程序列表启动 的优越性,因为不管是在什么时候按Home,再次从程序列表启动时,总能返回到Task的栈顶Activity。起初我想过一个办法,便是重载 Activity写一个类实现当onResume的时候更新Notification,然后我的所有Activity类都直接从该类继承,使得当按 Home 之后总能让Notification记住Task的栈顶Activity,就像QQ一样,但这种方法当然有点牵强,于是我开始看SDK 中 有关Home的Simple,终于发现了如果使用如下的Intent,便不会调用对应的Activity,而是调用Task中的栈顶Activity   Intent intent = new Intent(Intent.ACTION_MAIN);   intent.addCategory(Intent.CATEGORY_LAUNCHER);   intent.setClass(this, Main.class);   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);   除了 setClass 可以换成使用 setClassName 绑定,FLAG_ACTIVITY_RESET_TASK_IF_NEEDED可以不设,其他的选项都缺一不可。设置ACTION_MAIN与 CATEGORY_LAUNCHER是把该Intent发给了系统对应创建程序的模块,然后系统该模块根据设定的包与类信息还有flags进行处理。当然所有的Intent工作原理都是这样,只是对 ACTION_MAIN - CATEGORY_LAUNCHAR 的处理较为特殊,使得总是显示Task栈顶的Activity而不是setClass设定的Activity类。

2011-11-10 0comments 99hotness 0likes mikebai Read all
dev

Activity的启动模式(android:launchMode)

在android里,有4种activity的启动模式,分别为: “standard” (默认) “singleTop” “singleTask” “singleInstance” 它们主要有如下不同: 1. 如何决定所属task “standard”和”singleTop”的activity的目标task,和收到的Intent的发送者在同一个task内,除非intent包括参数FLAG_ACTIVITY_NEW_TASK。 如果提供了FLAG_ACTIVITY_NEW_TASK参数,会启动到别的task里。 “singleTask”和”singleInstance”总是把activity作为一个task的根元素,他们不会被启动到一个其他task里。 此话描述不正确, 感谢 liuluxu1989 提出。 这篇博文写的比较简单, 也没有任何图示, 不便大家理解, 建立大家直接看Dev guide.  或者下面这篇博文: http://marshal.easymorse.com/archives/2950 2. 是否允许多个实例 “standard”和”singleTop”可以被实例化多次,并且存在于不同的task中,且一个task可以包括一个activity的多个实例; “singleTask”和”singleInstance”则限制只生成一个实例,并且是task的根元素。 singleTop要求如果创建intent的时候栈顶已经有要创建 的Activity的实例,则将intent发送给该实例,而不发送给新的实例。 3. 是否允许其它activity存在于本task内 “singleInstance”独占一个task,其它activity不能存在那个task里;如果它启动了一个新的activity,不管新的activity的launch mode 如何,新的activity都将会到别的task里运行(如同加了FLAG_ACTIVITY_NEW_TASK参数)。 而另外三种模式,则可以和其它activity共存。 4. 是否每次都生成新实例 “standard”对于没一个启动Intent都会生成一个activity的新实例; “singleTop”的activity如果在task的栈顶的话,则不生成新的该activity的实例,直接使用栈顶的实例,否则,生成该activity的实例。 比如现在task栈元素为A-B-C-D(D在栈顶),这时候给D发一个启动intent,如果D是 “standard”的,则生成D的一个新实例,栈变为A-B-C-D-D。 如果D是singleTop的话,则不会生产D的新实例,栈状态仍为A-B-C-D 如果这时候给B发Intent的话,不管B的launchmode是”standard” 还是 “singleTop” ,都会生成B的新实例,栈状态变为A-B-C-D-B。 “singleInstance”是其所在栈的唯一activity,它会每次都被重用。 “singleTask”如果在栈顶,则接受intent,否则,该intent会被丢弃,但是该task仍会回到前台。 当已经存在的activity实例处理新的intent时候,会调用onNewIntent()方法 如果收到intent生成一个activity实例,那么用户可以通过back键回到上一个状态;如果是已经存在的一个activity来处理这个intent的话,用户不能通过按back键返回到这之前的状态。  

2011-11-10 0comments 120hotness 0likes mikebai Read all
dev

区分Activity的四种加载模式

在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。 这需要为Activity配置特定的加载模式,而不是使用默认的加载模式。 加载模式分类及在哪里配置 Activity有四种加载模式: standard singleTop singleTask singleInstance 设置的位置在AndroidManifest.xml文件中activity元素的android:launchMode属性: <activity android:name="ActB" android:launchMode="singleTask"></activity> 也可以在Eclipse ADT中图形界面中编辑: 区分Activity的加载模式,通过示例一目了然。这里编写了一个Activity A(ActA)和Activity B(ActB)循环跳转的例子。对加载模式修改和代码做稍微改动,就可以说明四种模式的区别。 standard 首先说standard模式,也就是默认模式,不需要配置launchMode。先只写一个名为ActA的Activity: package com.easymorse.activities; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class ActA extends Activity {     /** Called when the activity is first created. */     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         TextView textView = new TextView(this);         textView.setText(this + "");         Button button = new Button(this);         button.setText("go actA");         button.setOnClickListener(new OnClickListener() {             @Override             public void onClick(View v) {                 Intent intent = new Intent();                 intent.setClass(ActA.this, ActA.class);                 startActivity(intent);             }         });         LinearLayout layout = new LinearLayout(this);         layout.setOrientation(LinearLayout.VERTICAL);         layout.addView(textView);         layout.addView(button);         this.setContentView(layout);     } } 例子中都没有用layout,免得看着罗嗦。可见是ActA –> ActA的例子。在界面中打印出对象的toString值可以根据hash code识别是否创建新ActA实例。 第一个界面: 点击按钮后: 可以多点几次。发现每次都创建了该Activity的新实例。standard的加载模式就是这样的,intent将发送给新的实例。

2011-11-10 0comments 117hotness 0likes mikebai Read all
dev

java 嵌套类的实例化问题

No enclosing instance of type Foo is accessible. Must qualify the allocation with an enclosing instance of type Foo (e.g. x.new A() where x is an instance of Foo). You can get the error No enclosing instance of type Foo is accessible. Must qualify the allocation with an enclosing instance of type Foo (e.g. x.new A() where x is an instance of Foo). if you try to instantiate an inner class without an instance of the outer class. @@@ check! WRONG class Foo { private class Bar { // stuff } } class Baz { Foo.Bar aBar = new Foo.Bar(); // wrong! } WRONG class Foo { private class Bar { // stuff } } class Baz { Foo.Bar aBar = (new Foo).new Bar(); }

2011-11-08 0comments 108hotness 0likes mikebai Read all
dev

Android程序的真正入口Application

接触android已经有一段时间了,一直以为android程序的入口是配置文件中指定的Activity,最近看一个开源项目,发现里面实现了android 的Application类,才知道,android程序的真正入口是Application类的onCreate方法。只不过大多数开发者无需重写该类,它的继承关系如下图:java.lang.Object   ↳ android.content.Context     ↳ android.content.ContextWrapper       ↳ android.app.Applicationandroid.app.Application类包含了4个公开的方法   void  onConfigurationChanged(Configuration newConfig)   void  onCreate()  //这里才是真正的入口点。   void  onLowMemory()   void  onTerminate()下面是测试代码:使用application需要两个步骤:1.复写Application类,2.在配置文件中配置示例代码如下:MyApp类:package app.app;import android.app.Application;import android.content.res.Configuration;public class MyApp extends Application {@Overridepublic void onConfigurationChanged(Configuration newConfig) {  super.onConfigurationChanged(newConfig);}@Overridepublic void onCreate() {  super.onCreate();  System.out.println("MyApp is called");}@Overridepublic void onLowMemory() {  super.onLowMemory();}@Overridepublic void onTerminate() {  super.onTerminate();}}配置文件:<application android:icon="@drawable/icon" android:label="@string/app_name" android:name="app.app.MyApp" >  ......</application>Activity类:public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.main);  System.out.println("MainActivity is called");    }结果:MyApp is called       MainActivity is called      注释1:在Android中,Application只是一个松散的表征概念,没有多少实质上的表征[和J2me的Midlet有明显区别]。Application类,代表应用程序上下文状态,是一个极度弱化的概念。 Application只是一个空间范畴的概念,Application就是Activity,Service之类的组件上下文描述。 Application并不是Android的核心概念,而Activity才是Android的核心概念注释2:MyApplication类的作用是为了放一些全局的和一些上下文都要用到变量和方法。

2011-11-06 0comments 123hotness 0likes mikebai Read all
dev

android Notification 的使用

    最近一直在研究 android ,并一边研究一边做应用。其中遇到了把程序通知常驻在 Notification 栏,并且不能被 clear 掉(就像android QQ一样)的问题。经过研究实现了其功能,现把 Notification 的使用总结如下: Notification 的使用需要导入 3 个类1 import android.app.PendingIntent;2 import android.app.NotificationManager;3 import android.app.Notification; 代码示例及说明01 NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);              02 Notification n = new Notification(R.drawable.chat, "Hello,there!", System.currentTimeMillis());            03 n.flags = Notification.FLAG_AUTO_CANCEL;               04 Intent i = new Intent(arg0.getContext(), NotificationShow.class);05 i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);          06 //PendingIntent07 PendingIntent contentIntent = PendingIntent.getActivity(08         arg0.getContext(),09         R.string.app_name,10         i,11         PendingIntent.FLAG_UPDATE_CURRENT);12                  13 n.setLatestEventInfo(14         arg0.getContext(),15         "Hello,there!",16         "Hello,there,I'm john.",17         contentIntent);18 nm.notify(R.string.app_name, n); 下面依次对每一段代码进行分析:1 NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); 创建 NotificationManager,其中创建的 nm 对象负责“发出”与“取消”  Notification。1 Notification n = new Notification(R.drawable.chat, "Hello,there!", System.currentTimeMillis());            2 n.flags = Notification.FLAG_ONGOING_EVENT; 创建 Notification ,参数依次为:icon的资源id,在状态栏上展示的滚动信息,时间。其中创建的 n 对象用来描述出现在系统通知栏的信息,之后我们将会看到会在 n 对象上设置点击此条通知发出的Intent。1 n.flags = Notification.FLAG_AUTO_CANCEL; 设置 n.flags 为 Notification.FLAG_AUTO_CANCEL ,该标志表示当用户点击 Clear 之后,能够清除该通知。1 Intent i = new Intent(arg0.getContext(), NotificationShow.class);2 i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); 创建一个Intent,该Intent使得当用户点击该通知后发出这个Intent 请注意,如果要以该Intent启动一个Activity,一定要设置 Intent.FLAG_ACTIVITY_NEW_TASK 标记。 Intent.FLAG_ACTIVITY_CLEAR_TOP :如果在当前Task中,有要启动的Activity,那么把该Acitivity之前的所有Activity都关掉,并把此Activity置前以避免创建Activity的实例 Intent.FLAG_ACTIVITY_NEW_TASK :系统会检查当前所有已创建的Task中是否有该要启动的Activity的Task,若有,则在该Task上创建Activity,若没有则新建具有该Activity属性的Task,并在该新建的Task上创建Activity。更多请参见 “ (转载)Android下Affinities和Task ”1 //PendingIntent2 PendingIntent contentIntent = PendingIntent.getActivity(3         arg0.getContext(),4         R.string.app_name,5         i,6         PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent 为Intent的包装,这里是启动Intent的描述,PendingIntent.getActivity 返回的PendingIntent表示,此PendingIntent实例中的Intent是用于启动 Activity 的Intent。PendingIntent.getActivity的参数依次为:Context,发送者的请求码(可以填0),用于系统发送的Intent,标志位。 其中 PendingIntent.FLAG_UPDATE_CURRENT  表示如果该描述的PendingIntent已存在,则改变已存在的PendingIntent的Extra数据为新的PendingIntent的Extra数据。 这里再简要说一下 Intent 与 PendingIntent 的区别: Intent :意图,即告诉系统我要干什么,然后系统根据这个Inten

2011-11-06 0comments 107hotness 0likes mikebai Read all
dev

Android多线程的简要分析

在J2ME中,多线程的处理是很简单的,似乎并不用考虑很多问题,顶多是同步方面很让人头疼,而在Android中,一切似乎不那么明了了,很重要的一点是在其他线程中是不能直接访问主UI线程成员的。比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调用TextView.setText()的,在C#中也是这样,可能是为了主线程的安全吧。对于此类情况,Android提供了一些间接访问的方法。 1.runOnUiThread函数这个函数是Activity的成员函数,格式是public final void runOnUiThread (Runnable action)在自定义线程中执行对应Activity的runOnUiThread函数就好了,但是很明显,参数还是个线程,这个 函数基本上没什么意义。 2.Handler这应该是Android多线程中用的最多的工具了,这里Android借鉴了Windows的消息机制,不同线程之间可以用消息进行交流。除了主线程(UI线程)外,通过继承Thread或Runnable生成的线程是不包含消息循环(Looper)的。因此必须在线程中调用Looper.prepare()准备一个消息循环,调用Looper.loop()开始循环,就像是这样:class LooperThread extends Thread {      public Handler mHandler;      public void run() {          Looper.prepare();          mHandler = new Handler() {              public void handleMessage(Message msg) {                  // process incoming messages here              }          };          Looper.loop();      }}这其中Handler是用来接受并处理消息的,如果像上面写的那样调用无参数构造函数生成handler,这个Handler对应的就是所在线程,也可以用Looper做参数,这样生成的Handler对应的是Looper所在的线程。可以通过Looper.myLooper()获取当前线程的Looper。调用Handler对象的sendMessage(Message)函数可以向对应线程发送消息。例:public class ThreadMain extends Activity {    /** Called when the activity is first created. */private final static int MSG_BEGIN=1;private final static int MSG_END=2;    private ProgressDialog dialog=null;    private Button bt=null;    private Handler handle=new Handler(){    public void handleMessage(Message msg){       switch(msg.what){       case MSG_BEGIN:        showProgress();        break;              case MSG_END:        dismissProgress();        alertDialog();        break;       }       super.handleMessage(msg);    }    };       @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        bt=(Button)findViewById(R.id.bt);        bt.setOnClickListener(new OnClickListener(){    @Override    public void onClick(View v) {     // TODO Auto-generated method stub     doThread();    }});    }       private void doThread(){    new Thread(){       public void run(){        try{         sendMsg(MSG_BEGIN);         Thread.sleep(4000);         sendMsg(MSG_END);        }catch(Exception e){         e

2011-11-05 0comments 107hotness 0likes mikebai Read all
dev

ViewFlipper的使用

屏幕切换指的是在同一个Activity内屏幕见的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面;一个个性化设置页面。 通过查看OPhone API文档可以发现,有个android.widget.ViewAnimator类继承至FrameLayout,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果。该类有如下几个和动画相关的函数: l setInAnimation:设置View进入屏幕时候使用的动画,该函数有两个版本,一个接受单个参数,类型为android.view.animation.Animation;一个接受两个参数,类型为Context和int,分别为Context对象和定义Animation的resourceID。   setOutAnimation: 设置View退出屏幕时候使用的动画,参数setInAnimation函数一样。 showNext: 调用该函数来显示FrameLayout里面的下一个View。 showPrevious: 调用该函数来显示FrameLayout里面的上一个View。   一般不直接使用ViewAnimator而是使用它的两个子类ViewFlipper和ViewSwitcher。ViewFlipper可以用来指定FrameLayout内多个View之间的切换效果,可以一次指定也可以每次切换的时候都指定单独的效果。该类额外提供了如下几个函数:   isFlipping: 用来判断View切换是否正在进行 setFilpInterval:设置View之间切换的时间间隔 startFlipping:使用上面设置的时间间隔来开始切换所有的View,切换会循环进行 stopFlipping: 停止View切换 ViewSwitcher 顾名思义Switcher特指在两个View之间切换。可以通过该类指定一个ViewSwitcher.ViewFactory 工程类来创建这两个View。该类也具有两个子类ImageSwitcher、TextSwitcher分别用于图片和文本切换。 在教程中通过示例介绍ViewFlipper 的使用,其他的使用方式是类似的。详细信息可以参考文档: http://androidappdocs-staging.appspot.com/reference/android/widget/ViewAnimator.html   ViewFlipper示例 记住,ViewFlipper是继承至FrameLayout的,所以它是一个Layout里面可以放置多个View。在示例中定义一个ViewFlipper,里面包含三个ViewGroup作为示例的三个屏幕,每个ViewGroup中包含一个按钮和一张图片,点击按钮则显示下一个屏幕。代码如下(res\layout\main.xml): view plaincopy to clipboardprint? <?xml version="1.0" encoding="utf-8"?>    <LinearLayout        xmlns:android="http://schemas.android.com/apk/res/android"       android:orientation="vertical"         android:layout_width="fill_parent"       android:layout_height="fill_parent">        <ViewFlipper android:id="@+id/details"          android:layout_width="fill_parent"            android:layout_height="fill_parent"          android:persistentDrawingCache="animation"        

2011-09-26 0comments 132hotness 0likes mikebai Read all
1…1617181920…25

Recent Posts

  • c# winform适配高dpi
  • com.microsoft.sqlserver.jdbc.SQLServerException “trustServerCertificate”属性设置为“false”,但驱动程序无法使用安全套接字层 (SSL) 加密与 SQL Server建立安全连接
  • java -cp 用法介绍
  • HTML 容器元素
  • MVC的cshtml的介绍

Recent Comments

No comments to show.

COPYRIGHT © 2025 mikebai.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang