当前位置:  编程技术>移动开发
本页文章导读:
    ▪activity中的起动模式        activity中的启动模式 Activity的加载模式            在上一文中,我们说过,Activity就相当于一块块的七巧板,每个应用用这一个个七巧板组合成了美丽的图画,并用代码验证了每个Activit.........
    ▪ 判断联系人是不是存在        判断联系人是否存在 联系人存储包括两个位置:SIM卡和手机上,在查找过程中要分别判断。手机上存储位置在/data/data/com/android.providers.contacts/databases。1 判断是否存储在手机上(CallDetailAct.........
    ▪ ProgressDialog 响应 返回键的有关问题       ProgressDialog 响应 返回键的问题 http://www.eoeandroid.com/thread-61478-1-1.html引用我发现了一个问题:如下2种方式创建的ProgressDialog,方式1能响应返回键,即按下返回键时,ProgressDialog消失;方式2不能.........

[1]activity中的起动模式
    来源: 互联网  发布时间: 2014-02-18
activity中的启动模式

Activity的加载模式 

  

  

    在上一文中,我们说过,Activity就相当于一块块的七巧板,每个应用用这一个个七巧板组合成了美丽的图画,并用代码验证了每个Activity的生命周期。
    那么,每个应用又是如何将各个Activity组合起来的呢?这就是本文要讲的内容。
    通常情况下,一个应用有一个Task,这个Task就是为了完成某个工作的一系列Activity的集合。而这些Activity又被组织成了堆栈的形式。
    当一个Activity启动时,就会把它压入该Task的堆栈,而当用户在该Activity中按返回键,或者代码中finish掉时,就会将它从该Task的堆栈中弹出。如果我们没有特别的需求,我们的应用就会呈现出如下图所示的情形(好吧,我承认这个图是document里的):

    然而,事实上我们的需求远没有我们想的那么简单。有时候,你可能希望在开启一个Activity时,重新开启一个Task;有时你可能希望将已经存在的一个Activity放到栈顶,而不是重新创建一个...
    Android为了使我们能够打破默认的堆栈的先后出的模式,提供了两个种方式:一种是在AndroidManifest.xml定义Activity时指定它的加载模式,另一种是在用Intent开启一个Activity时,在Intent中加入标志。如果两种方式都用了,则后者的优先级更高。
    两种方式的差别在于,前者在于描述自己,向别的Acttivity等声明你们如何来加载我;而后者则是动态的,指出我要求你(要启动的Activity)如何来加载。本文的重点在于研究在AndroidManifest.xml中声明加载模式。

    Android为我们定义了四种加载模式,分别是:standard、singleTop、singleTask和singleInstance。

    “拿来主义”——standard模式
     我们写一段代码来测试一下standard加载模式,如下
     AndroidManifest.xml里Activity的设置如下:

1.  <activity android:name=".Activity1" 

2.            android:launchMode="standard" 

3.            android:label="@string/app_name"> 

4.      <intent-filter> 

5.          <action android:name="android.intent.action.MAIN" /> 

6.          <category android:name="android.intent.category.LAUNCHER" /> 

7.      </intent-filter> 

8.  </activity> 

     Activity1的代码如下:

1.  public class Activity1 extends Activity {  

2.      @Override 

3.      public void onCreate(Bundle savedInstanceState) {  

4.          super.onCreate(savedInstanceState);  

5.          setContentView(R.layout.main);  

6.      }  

7.   

8.      /**当点击Activity时,启动另一个Activity1*/ 

9.      @Override 

10.    public boolean onTouchEvent(MotionEvent event) {  

11.        Intent intent = new Intent(this, Activity1.class);  

12.        startActivity(intent);  

13.        return super.onTouchEvent(event);  

14.    }  

15.} 

    然后我们启动程序,开启Activity1,然后点击Acitivity1,启动另一个Activity1,然后再点击,再点击,再点击... 之后我们点返回键。
    发生了什么事情?没错,我们按返回键返回一个又一个相同的Activity1。
    standard是Activity默认的加载模式,这种方式用一个词来形容的话就是“拿来主义”。使用这种模式的Activity向所有使用它的Task声明:“我这里的这种Activity多着呢,谁需要的话我就给谁”。所以当一个Task请求加载这个Activity时,该Task直接实例化该Activity,并把它放到栈顶。
    因此我们的例子就出现了这样的堆栈结构(假设我们点击了4次):

Activity1

Activity1

Activity1

Activity1

Activity1

    我们设想一个情形:我们要做一个图片浏览器,第一个界面是图片列表界面(假设为PictureListActivity),第二个界面是浏览该张图片(假设为PictureViewActivity)。在PictureViewActivity中可以startActivity启动浏览界面浏览上一张和下一张。
    如果每一张图片的浏览启动一个PictureViewActivity(当然你可能不是采用这种方式来浏览上一张和下一张,这里只是举个例子),如果采用standard模式的话,就会出现多个PictureViewActivity在堆栈中堆叠的情形。下面介绍的singleTop便可以解决这个问题。


    “拒绝堆叠”——singleTop模式

    我们将上面的例子稍加改动,AndroidManifest.xml中Acitivity1的launchMode改为singleTop,Activity1的代码修改如下:

1.  public class Activity1 extends Activity {  

2.      @Override 

3.      public void onCreate(Bundle savedInstanceState) {  

4.          super.onCreate(savedInstanceState);  

5.          setContentView(R.layout.main);  

6.          //Activity1创建时显示Toast  

7.          Toast.makeText(this, "onCreate called!", Toast.LENGTH_SHORT).show();  

8.      }  

9.        

10.    @Override 

11.    protected void onNewIntent(Intent intent) {  

12.        setTitle("I am Activity1 too, but I called onNewIntent!");  

13.        super.onNewIntent(intent);  

14.    }  

15.      

16.    //点击进入加载Activity1  

17.    @Override 

18.    public boolean onTouchEvent(MotionEvent event) {  

19.        Intent intent = new Intent(this, Activity1.class);  

20.        startActivity(intent);  

21.        return super.onTouchEvent(event);  

22.    }  

23.} 

    同样,我们启动程序,开启Activity1,然后点击Acitivity1,启动另一个Activity1,然后再点击,再点击,再点击... 之后我们点返回键。
    结果,Activity1第一次创建时,显示一个Toast提示,onCreate被调用,当再次点击时,onCreate没有被调用相反是进入了onNewIntent函数。当按返回键时,直接退出了该应用,可见,堆栈中只存在一个Acitivity1。
    可见,当activity被设置为singleTop的加载模式时,如果堆栈的顶部已经存在了该Activity,那么,它便不会重新创建,而是调用onNewIntent。如果,该Activity存在,但不是在顶部,那么该Activity依然要重新创建,请读者自行验证。
    因此singleTop模式的思想便是“拒绝堆叠”!
    以上说的两种加载模式,Activity均可以实例化多次,而下面讲的两个加载模式就只可以实例化一次。

    “独立门户”——singleTask模式

    我们首先测试一下,在本应用内调用singleTask模式的Activity会出现什么情况。

    我们写两个Activity(Activity1和Activity2),相互调用,其中Activity1为singleTask模式。AndroidManifest.xml如下:

1.  <application android:icon="@drawable/icon" android:label="@string/app_name"> 

2.      <activity android:name=".Activity1" 

3.                android:launchMode="singleTask" 

4.                android:label="@string/app_name"> 

5.      </activity> 

6.      <activity android:name=".Activity2"> 

7.          <intent-filter> 

8.              <action android:name="android.intent.action.MAIN" /> 

9.              <category android:name="android.intent.category.LAUNCHER" /> 

10.        </intent-filter> 

11.    </activity> 

12.</application> 

    两个Activity的代码如下:

 /**Activity1的代码*/

1.  public class Activity1 extends Activity {  

2.      private static final String TAG = "Activity1";  

3.      @Override 

4.      public void onCreate(Bundle savedInstanceState) {  

5.          super.onCreate(savedInstanceState);  

6.          setContentView(R.layout.main);  

7.          Log.e(TAG, "Activity1 onCreate! HashCode=" + this.hashCode() + " TaskId=" + getTaskId());   

8.      }  

9.        

10.    @Override 

11.    protected void onNewIntent(Intent intent) {  

12.        Log.e(TAG, "Activity1 onNewIntent! HashCode="+ this.hashCode() + " TaskId=" + getTaskId());  

13.        super.onNewIntent(intent);  

14.    }  

15.      

16.    @Override 

17.    protected void onDestroy() {  

18.        Log.e("Activity1", "Activity1 onDestroy! HashCode="+this.hashCode()+ "TaskId="+getTaskId());  

19.        super.onDestroy();  

20.    }  

21.         

22.    /**点击进入Activity2*/ 

23.    @Override 

24.    public boolean onTouchEvent(MotionEvent event) {  

25.        Intent intent = new Intent(this, Activity2.class);  

26.        startActivity(intent);  

27.        return super.onTouchEvent(event);  

28.    }  

29.} 

1.  /**Activity2的代码*/ 

2.  public class Activity2 extends Activity {  

3.      private static final String TAG = "Activity2";  

4.      @Override 

5.      protected void onCreate(Bundle savedInstanceState) {  

6.          super.onCreate(savedInstanceState);  

7.          setContentView(R.layout.main2);  

8.          Log.e(TAG, "Activity2 onCreated! HashCode=" + this.hashCode() + " TaskId="+getTaskId());  

9.      }  

10.          

11.    @Override 

12.    protected void onDestroy() {  

13.        Log.e(TAG, "Activity2 onDestroy! HashCode="+this.hashCode()+" TaskId="+getTaskId());  

14.        super.onDestroy();  

15.    }  

16.      

17.    /**点击进入Activity1*/ 

18.    @Override 

19.    public boolean onTouchEvent(MotionEvent event) {  

20.        Intent intent = new Intent(this, Activity1.class);  

21.        startActivity(intent);  

22.        return super.onTouchEvent(event);  

23.    }  

24.} 

    从代码中我们可以看出,每当两个Activity创建、销毁以及onNewIntent时,都会打印该Activity的HashCode和所在的Task id。

    我们的操作步骤是这样的,打开应用程序,默认启动Activity2,点击Activity2,进入Activity1,再点击Activity1进入Activity2,再点击Activity2进入Activity1,然后按返回键,直到返回到Home。

    晕了吧,好写个顺序来形象的表示下:Activity2->Activity1(singleTask)->Activity2->Activity1(singleTask)。^_^

    进入Activity2,然后到Activity1,我们看Log信息为:

    03-01 14:50:08.144: ERROR/Activity2(371): Activity2 onCreated! HashCode=1156067168 TaskId=7
    03-01 14:50:13.923: ERROR/Activity1(371): Activity1 onCreate! HashCode=1156107384 TaskId=7
    我们看到,当本应用启动singleTask的Activity(Activity1)时,Activity1并没用另外启用一个任务。而是在原来的任务中创建了它。

    再从Activity1进入Activity2,然后再进入Activity1,这个过程,我们再看log信息:

    03-01 14:53:50.823: ERROR/Activity2(371): Activity2 onCreated! HashCode=1156128904 TaskId=7
    03-01 14:53:58.154: ERROR/Activity1(371): Activity1 onNewIntent! HashCode=1156107384 TaskId=7
    03-01 14:53:58.394: ERROR/Activity2(371): Activity2 onDestroy! HashCode=1156128904 TaskId=7
    从这个Log信息我们可以得到这个结论:当singleTask模式的Activity启动时,如果发现在某个Task中已经存在,那么它会先将该Activity(Activity1)上部的Activity(Activity2)销毁,然后调用它(Activity1)的onNewIntent函数。

    我们下面来研究一下当singleTask的Activity被其他应用调用时的情况。

    为了使Activity1能够被其他应用程序调用,我们在AndroidManifest.xml中加入action,如下:

1.  <activity android:name=".Activity1" 

2.            android:launchMode="singleTask" 

3.            android:label="@string/app_name"> 

4.      <intent-filter> 

5.          <action android:name="com.winuxxan.singleTask" /> 

6.          <category android:name="android.intent.category.DEFAULT" /> 

7.      </intent-filter> 

8.  </activity> 

    然后我们另外创建一个工程,创建一个Activity在初始化的时候启动Activity1,代码如下:

1.  public class MyActivity extends Activity {  

2.      @Override 

3.      public void onCreate(Bundle savedInstanceState) {  

4.          super.onCreate(savedInstanceState);  

5.          setContentView(R.layout.main);  

6.          Log.e("MyActivity", "TaskId=" + getTaskId());  

7.          Intent intent = new Intent("com.winuxxan.singleTask");  

8.          startActivity(intent);  

9.      }  

10.} 

    我们的操作方法是,MyActivity->Activity1->Activity2->Activity1,之后我们按Home键,然后再从Home重新进入MyActivity所在的应用。

    首先看MyActivity->Activity1这个过程,我们查看Log信息如下:

    03-01 15:04:25.784: ERROR/MyActivity(429): TaskId=9
    03-01 15:04:26.244: ERROR/Activity1(401): Activity1 onCreate! HashCode=1156107632 TaskId=10
    从这个Log信息我们可以看出:当某个应用调用其他应用里声明的singleTask模式的Activity时,它会重新创建一个Task,然后将该Activity实例化并压入堆栈。

    接着我们看Activity1和Activity2的相互切换,log信息如下:

    03-01 15:04:47.524: ERROR/Activity2(401): Activity2 onCreated! HashCode=1156128104 TaskId=10
    03-01 15:04:50.674: ERROR/Activity1(401): Activity1 onNewIntent! HashCode=1156107632 TaskId=10
    03-01 15:04:50.994: ERROR/Activity2(401): Activity2 onDestroy! HashCode=1156128104 TaskId=10
    和我们所期望的那样,如果Activity发现已经存在时,会销毁其上的Activity,然后调用onNewIntent。

    之后,我们按Home键,返回桌面,然后,再次进入该应用,我们神奇的发现,我们进入的是MyActivity界面,taskId为10的所有Activity不知了踪影!

    这是因为,该应用对应的task的id为9,所以,进入后之后MyActivity在该task中,所以最后显示的是MyActivity。我的以上Activity1的代码实际上是不好的习惯,因为Activity1很可能会成为一个孤岛,所以建议,如果该Activity的类型不是LAUNCHER,最好不要设为singleTask。

    那么singleTask的这些特性有什么用处?我们举一个例子,浏览器就是一个singleTask的例子,启动一个浏览器,在Android中是一个比较沉重的过程,它需要做很多初始化的工作,并且会有不小的内存开销。如果有多个应用都来请求打开网页,那么系统就不会不堪重负。因此,如果浏览器采用singleTask模式,如果有多个请求打开网页的请求,都会在一个Task中响应,这样就会避免以上的情况。

    “孤独寂寞”——singleInstance模式

    我们现在来研究最后一个加载模式,singgleInstance,测试很简单,我们只要在singleTask测试的例子中,将Activity1的模式改为singleInstance模式即可。

    我们首先进行同一应用内部的测试。

    首先Activity2->Activity1,观察log信息:

    03-01 15:41:59.283: ERROR/Activity2(488): Activity2 onCreated! HashCode=1156067168 TaskId=12
    03-01 15:42:04.103: ERROR/Activity1(488): Activity1 onCreate! HashCode=1156107520 TaskId=13
    我们发现,当采用singleInstance模式时,启动时创建了一个新的Task,并将Activity1实例化加入到该Task中。

    然后我们Activity1->Activity2->Activity1,观察log信息:

    03-01 15:43:52.214: ERROR/Activity2(488): Activity2 onCreated! HashCode=1156127728 TaskId=12
    03-01 15:43:56.804: ERROR/Activity1(488): Activity1 onNewIntent! HashCode=1156107520 TaskId=13
    我们通过该log信息可以得出结论:singleInstance的Activity(Activity1)不允许其他的Activity(Activity2)加入到自己的Task中,它是的内心容不下另一个人,它是一个孤独寂寞的人。 当Activity1发现已经存在一个Task中包含自己的实例时,它会调用自己的onNewIntent。

    然后,我们同样也测试一下,如果其它应用程序调用Activity1会出现什么样的情况:

    MyActivity->Activity1, 观察log信息:

    03-01 15:50:21.134: ERROR/MyActivity(556): TaskId=16
    03-01 15:50:21.484: ERROR/Activity1(534): Activity1 onCreate! HashCode=1156107344 TaskId=17
    不出意料,Activity1重新创建了一个Task,并将自己的实例入栈。

    Activity1->Activity2->Activity1->Activity2, 我们观察log信息:

    03-01 15:50:36.484: ERROR/Activity2(534): Activity2 onCreated! HashCode=1156128056 TaskId=18
    03-01 15:50:46.114: ERROR/Activity1(534): Activity1 onNewIntent! HashCode=1156107344 TaskId=17
    我们从该过程可以看出:如果从其它应用程序调用singleInstance模式的Activity(Activity1),从该Activity开启其他Activity(Activity2)时,会创建一个新的Task(task id为18的那个),实际上,如果包含该Activity(Activity2)的Task已经运行的话,他会在该运行的Task中重新创建。

    OK,上面啰嗦了那么多,如果这部分不是很清楚的人,可能已经头昏脑胀了。那我们总结一下吧,这总该看看了吧。

    “拿来主义”standard模式。哪里需要调用我我就去哪里,可以多次实例化,可以几个相同的Activity重叠。

    “拒绝堆叠”singleTop模式。可以多次实例化,但是不可以多个相同的Activity重叠,当堆栈的顶部为相同的Activity时,会调用onNewIntent函数。

    “独立门户”singleTask模式。同一个应用中调用该Activity时,如果该Activity没有被实例化,会在本应用程序的Task内实例化,如果已经实例化,会将Task中其上的Activity销毁后,调用onNewIntent;其它应用程序调用该Activity时,如果该Activity没有被实例化,会创建新的Task并实例化后入栈,如果已经实例化,会销毁其上的Activity,并调用onNewIntent。一句话,singleTask就是“独立门户”,在自己的Task里,并且启动时不允许其他Activity凌驾于自己之上。

    “孤独寂寞”singleInstance模式。加载该Activity时如果没有实例化,他会创建新的Task后,实例化入栈,如果已经存在,直接调用onNewIntent,该Activity的Task中不允许启动其它的Activity,任何从该Activity启动的其他Activity都将被放到其他task中,先检查是否有本应用的task,没有的话就创建。

附:由于android文档中的解释不是很清楚,所以做了上述测试,结论也是根据测试得出的结论,singleTask和singInstance的任务创建还跟taskAffience有关,我们下次再研究。如果有不对的地方请大家赶快指正,以防影响他人。多谢。

 

 

B.R
Hongcheng

Confidentiality Notice:
The opinions and views expressed in this e-mail are solely those of the author and do not necessarily represent those of YuHua TelTech and its affiliates. YuHua TelTech is not responsible for any liability or damaged caused by viruses transmitted with this e-mail or its attachments. If this e-mail is not originally intended for you, or received by you in error, do not disclose,duplicate,distribute,or use its content to anyone and delete it immediately. This e-mail may contain information that is legally privileged, confidential,or exempt from disclosure.
本邮件所包含之观点及内容,完全是邮件作者独立意见,不代表禹华通信及其分支机构之立场。禹华通信将不对本邮件有可能包含的病毒所引起的损害承担责任。若您并非收件人或错收本邮件,请勿披露、复制、散布或使用本邮件中的任何信息,并请即刻予以删除。本邮件所包含之内容完全是受法律保护的保密信息,应免予被披露


    
[2] 判断联系人是不是存在
    来源: 互联网  发布时间: 2014-02-18
判断联系人是否存在
联系人存储包括两个位置:SIM卡和手机上,在查找过程中要分别判断。

手机上存储位置在/data/data/com/android.providers.contacts/databases。

1 判断是否存储在手机上(CallDetailActivity)
Uri personUri = null;
                    Uri phoneUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
                            Uri.encode(mNumber));
                    Cursor phonesCursor = resolver.query(phoneUri, PHONES_PROJECTION, null, null, null);
                    try {
                        if (phonesCursor != null && phonesCursor.moveToFirst()) {
                            long personId = phonesCursor.getLong(COLUMN_INDEX_ID);
                            personUri = ContentUris.withAppendedId(
                                    Contacts.CONTENT_URI, personId);
                            callText = getString(R.string.recentCalls_callNumber,
                                    phonesCursor.getString(COLUMN_INDEX_NAME));
                            mNumber = PhoneNumberUtils.formatNumber(
                                    phonesCursor.getString(COLUMN_INDEX_NUMBER));
                            callLabel = Phone.getDisplayLabel(this,
                                    phonesCursor.getInt(COLUMN_INDEX_TYPE),
                                    phonesCursor.getString(COLUMN_INDEX_LABEL)).toString();
                        } else {
                            mNumber = PhoneNumberUtils.formatNumber(mNumber);
                        }
                    } finally {
                        if (phonesCursor != null) phonesCursor.close();
                    }

还可以用以下几种方式搜索:
 Cursor cursor = this.getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
                projection, //返回字段
                ContactsContract.CommonDataKinds.Phone.NUMBER + " = '" + mNumber + "'", // 
                null, // WHERE clause value substitution
                null); // Sort order.

判断是否存在SIM卡上(CallDetailActivity)
Cursor simCursor=null;
                        String[] SIM_CONTENT_PROJECTION = new String[] {
                                "name", "number", };
                        boolean hasIccCard1 = ((TelephonyManager) this .getSystemService(
                                PhoneFactory.getServiceName(Context.TELEPHONY_SERVICE, 0))).hasIccCard();

                        if(hasIccCard1){
                            simCursor = resolver.query(EditSimCardActivity.SIM1_URI,SIM_CONTENT_PROJECTION, null, null, null);
                            try {
                                if (simCursor != null) {
                                    if (simCursor.moveToFirst()) {
                                        do {
                                            String tempName = simCursor.getString(0);
                                            String tempNumber = simCursor.getString(1);
                                            if (mNumber.equals(tempNumber)) {
                                                hasFoundContact=true;
                                                simContactIntent=new Intent();
                                                simContactIntent.setClass(this, ViewSimCardContactActivity.class);
                                                simContactIntent.putExtra(EditSimCardActivity.SIM_CONTACT_NAME, tempName);
                                                simContactIntent.putExtra(EditSimCardActivity.SIM_CONTACT_NUMBER, tempNumber);
                                                simContactIntent.putExtra(EditSimCardActivity.SIM_ADDRESS, EditSimCardActivity.SIM1_ADDRESS);
                                                callText = getString(R.string.recentCalls_callNumber,tempName);
                                                mNumber = PhoneNumberUtils.formatNumber(tempNumber);
                                                break;
                                            }
                                        } while (simCursor.moveToNext());
                                    }
                                    simCursor.close();
                                }
                            } finally {
                                if (simCursor != null) simCursor.close();
                            }
                        }

打开联系人详情页面(CallDetailActivity)
if (personUri != null) { //phone
                        Intent viewIntent = new Intent(Intent.ACTION_VIEW, personUri);
                        actions.add(new ViewEntry(R.drawable.sym_action_view_contact,
                                getString(R.string.menu_viewContact), viewIntent));
                    } else if (simContactIntent != null) { //sim
                        actions.add(new ViewEntry(R.drawable.sym_action_view_contact,
                                getString(R.string.menu_viewContact), simContactIntent));
                    } else { // none
                        Intent createIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
                        createIntent.setType(Contacts.CONTENT_ITEM_TYPE);
                        createIntent.putExtra(Insert.PHONE, mNumber);
                        actions.add(new ViewEntry(R.drawable.sym_action_add,
                                getString(R.string.recentCalls_addToContact), createIntent));
                    }

    
[3] ProgressDialog 响应 返回键的有关问题
    来源: 互联网  发布时间: 2014-02-18
ProgressDialog 响应 返回键的问题


http://www.eoeandroid.com/thread-61478-1-1.html

引用
我发现了一个问题:如下2种方式创建的ProgressDialog,方式1能响应返回键,即按下返回键时,ProgressDialog消失;方式2不能响应返回键,即按下返回键时,ProgressDialog不会消失。
方式1:

ProgressDialog mProgressDialog=new ProgressDialog(this);
mProgressDialog.setTitle("标题");
mProgressDialog.setMessage("内容");
mProgressDialog.show();

方式2:
Progress progress=ProgressDialog.show(this, "标题", "内容");
progress.show();

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3