• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            life02

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              197 隨筆 :: 3 文章 :: 37 評論 :: 0 Trackbacks
            Android面試題
            http://topic.csdn.net/u/20101219/21/b6f83d6f-35b5-49ea-b281-d47ca662ea17.html?57324
            1. 請描述下Activity的生命周期。
            2. 如果后臺的Activity由于某原因被系統(tǒng)回收了,如何在被系統(tǒng)回收之前保存當(dāng)前狀態(tài)?
            3. 如何將一個Activity設(shè)置成窗口的樣式。(Edited by Sodino)
            4. 如何退出Activity?如何安全退出已調(diào)用多個Activity的Application?
            5. 請介紹下Android中常用的五種布局。
            6. 請介紹下Android的數(shù)據(jù)存儲方式。(Edited by Sodino)
            7. 請介紹下ContentProvider是如何實現(xiàn)數(shù)據(jù)共享的。(Edited by Sodino)
            8. 如何啟用Service,如何停用Service。(Edited by Sodino)
            9. 注冊廣播有幾種方式,這些方式有何優(yōu)缺點?請談?wù)凙ndroid引入廣播機制的用意。
            10. 請解釋下在單線程模型中Message、Handler、Message Queue、Looper之間的關(guān)系。
            11. AIDL的全稱是什么?如何工作?能處理哪些類型的數(shù)據(jù)?
            12. 請解釋下Android程序運行時權(quán)限與文件系統(tǒng)權(quán)限的區(qū)別。(Edited by Sodino)
            13. 系統(tǒng)上安裝了多種瀏覽器,能否指定某瀏覽器訪問指定頁面?請說明原由。
            14. 有一個一維整型數(shù)組int[]data保存的是一張寬為width,高為height的圖片像素值信息。請寫一個算法,將該圖片所有的白色不透明(0xffffffff)像素點的透明度調(diào)整為50%。
            15. 你如何評價Android系統(tǒng)?優(yōu)缺點。


            1.activity的生命周期。 

            2.橫豎屏切換時候activity的生命周期 

            總結(jié):

            1、不設(shè)置Activity的android:configChanges時,切屏?xí)匦抡{(diào)用各個生命周期,切橫屏?xí)r會執(zhí)行一次,切豎屏?xí)r會執(zhí)行兩次

            2、設(shè)置Activity的android:configChanges="orientation"時,切屏還是會重新調(diào)用各個生命周期,切橫、豎屏?xí)r只會執(zhí)行一次

            3、設(shè)置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調(diào)用各個生命周期,只會執(zhí)行onConfigurationChanged方法


            3.android中的動畫有哪幾類,它們的特點和區(qū)別是什么 


            4.handler機制的原理 


            5.說說activity,intent,service是什么關(guān)系 

            6.android中線程與線程,進(jìn)程與進(jìn)程之間如何通信 

            7.widget相對位置的完成在antivity的哪個生命周期階段實現(xiàn) 

            8.說說mvc模式的原理,它在android中的運用 

            9.說說在android中有哪幾種數(shù)據(jù)存儲方式 

            10.android中有哪幾種解析xml的類,官方推薦哪種?以及它們的原理和區(qū)別

            3. 如何將一個Activity設(shè)置成窗口的樣式。
              設(shè)置Activity窗口化:
              android:theme="@android:style/Theme.Dialog"
              設(shè)置Activity透明化:  
              android:theme="@android:style/Theme.Translucent"
            6. 請介紹下Android的數(shù)據(jù)存儲方式
              ㈠.文件存儲方式:
            在Android中通常使用File存儲方式是用 Context.openFileOutput(String fileName, int mode)和Context.openFileInput(String fileName)。
              Context.openFileOutput(String fileName, int mode)生成的文件自動存儲在/data/data/PackageName/file目錄下,其全路徑是/data/data/Package Name/files/fileName 。注意下,這里的參數(shù)fileName不可以包含路徑分割符(如"/")。
              通常來說,這種方式生成的文件只能在這個apk內(nèi)訪問。但這個結(jié)論是指使用Context.openFileInput(String fileName)的方式。使用這種方式,每個apk只可以訪問自己的/data/data/Package Name/files目錄下的文件,原因很簡單,參數(shù)fileName中不可以包含路徑分割符,Android會自動在/data/data /Package Name/files目錄下尋找文件名為fileName的文件。
            具體實例如下:
            String fn = “moandroid.log”;
            FileInputStream fis = openFileInput(fn);
            FileOutputStream fos = openFileOutput(fn.Context.MODE_PRIVATE);

            ㈡.使用SharedPreferences存儲數(shù)據(jù)
            首先說明SharedPreferences存儲方式,它是 Android提供的用來存儲一些簡單配置信息的一種機制,例如:登錄用戶的用戶名與密碼。其采用了Map數(shù)據(jù)結(jié)構(gòu)來存儲數(shù)據(jù),以鍵值的方式存儲,可以簡單的讀取與寫入,具體實例如下:
              void ReadSharedPreferences(){
              String strName,strPassword;
              SharedPreferences user = getSharedPreferences(“user_info”,0);
              strName = user.getString(“NAME”,””);
              strPassword = user getString(“PASSWORD”,””);
              }
              void WriteSharedPreferences(String strName,String strPassword){
              SharedPreferences user = getSharedPreferences(“user_info”,0);
              uer.edit()//獲得編輯器;
              user.putString(“NAME”, strName);
              user.putString(“PASSWORD” ,strPassword);
              user.commit();
              }
              數(shù)據(jù)讀取與寫入的方法都非常簡單,只是在寫入的時候有些區(qū)別:先調(diào)用edit()使其處于編輯狀態(tài),然后才能修改數(shù)據(jù),最后使用commit()提交修改的數(shù)據(jù)。實際上SharedPreferences是采用了XML格式將數(shù)據(jù)存儲到設(shè)備中,在DDMS中的File Explorer中的/data/data/<package name>/shares_prefs下。以上面的數(shù)據(jù)存儲結(jié)果為例,打開后可以看到一個user_info.xml的文件,打開后可以看到:
              <?xml version=”1.0″ encoding=”UTF-8″?>
              <map>
              <string name=”NAME”>moandroid</string>
              <string name=” PASSWORD”>SharedPreferences</string>
              </map>
            使用SharedPreferences是有些限制的:只能在同一個包內(nèi)使用,不能在不同的包之間使用。

            ㈢:網(wǎng)絡(luò)存儲數(shù)據(jù)
            網(wǎng)絡(luò)存儲方式,需要和Android網(wǎng)絡(luò)數(shù)據(jù)包打交道。

            ㈣.ContentProvider數(shù)據(jù)存儲
            1、ContentProvider簡介
            當(dāng)應(yīng)用繼承ContentProvider類,并重寫該類用于提供數(shù)據(jù)和存儲數(shù)據(jù)的方法,就可以向其他應(yīng)用共享其數(shù)據(jù)。雖然使用其他方法也可以對外共享數(shù)據(jù),但數(shù)據(jù)訪問方式會因數(shù)據(jù)存儲的方式而不同,如:采用文件方式對外共享數(shù)據(jù),需要進(jìn)行文件操作讀寫數(shù)據(jù);采用sharedpreferences共享數(shù)據(jù),需要使用sharedpreferences API讀寫數(shù)據(jù)。而使用ContentProvider共享數(shù)據(jù)的好處是統(tǒng)一了數(shù)據(jù)訪問方式。與之相關(guān)聯(lián)的是uri,下面是uri的簡介:
            2、Uri類簡介
            Uri代表了要操作的數(shù)據(jù),Uri主要包含了兩部分信息:需要操作的ContentProvider和對ContentProvider中的什么數(shù)據(jù)進(jìn)行操作,一個Uri由以下幾部分組成:
              1).scheme:ContentProvider(內(nèi)容提供者)的scheme已經(jīng)由Android所規(guī)定為:content://。
              2).主機名(或Authority):用于唯一標(biāo)識這個ContentProvider,外部調(diào)用者可以根據(jù)這個標(biāo)識來找到它。
              3).路徑(path):可以用來表示我們要操作的數(shù)據(jù),路徑的構(gòu)建應(yīng)根據(jù)業(yè)務(wù)而定,如下:
              要操作contact表中id為10的記錄,可以構(gòu)建這樣的路徑:/contact/10
              要操作contact表中id為10的記錄的name字段, contact/10/name
              要操作contact表中的所有記錄,可以構(gòu)建這樣的路徑:/contact?
              要操作的數(shù)據(jù)不一定來自數(shù)據(jù)庫,也可以是文件等他存儲方式,如下:
              要操作xml文件中contact節(jié)點下的name節(jié)點,可以構(gòu)建這樣的路徑:/contact/name
            如果要把一個字符串轉(zhuǎn)換成Uri,可以使用Uri類中的parse()方法,如下:
            Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")
              3、UriMatcher、ContentUrist和ContentResolver簡介
            因為Uri代表了要操作的數(shù)據(jù),所以我們很經(jīng)常需要解析Uri,并從 Uri中獲取數(shù)據(jù)。Android系統(tǒng)提供了兩個用于操作Uri的工具類,分別為UriMatcher 和ContentUris 。掌握它們的使用,會便于我們的開發(fā)工作。
            ? UriMatcher:用于匹配Uri,它的用法如下:
              1).首先把你需要匹配Uri路徑全部給注冊上,如下:
            //常量UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼(-1)。
            UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
            //如果match()方法匹配content://com.changcheng.sqlite.provider.contactprovider /contact路徑,返回匹配碼為1
            uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact”, 1);//添加需要匹配uri,如果匹配就會返回匹配碼
            //如果match()方法匹配 content://com.changcheng.sqlite.provider.contactprovider/contact/230路徑,返回匹配碼為2
            uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact/#”, 2);//#號為通配符

              2).注冊完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法對輸入的Uri進(jìn)行匹配,如果匹配就返回匹配碼,匹配碼是調(diào)用 addURI()方法傳入的第三個參數(shù),假設(shè)匹配 content://com.changcheng.sqlite.provider.contactprovider/contact路徑,返回的匹配碼為1。

            ContentUris:用于獲取Uri路徑后面的ID部分,它有兩個比較實用的方法:
             withAppendedId(uri, id)用于為路徑加上ID部分
             parseId(uri)方法用于從路徑中獲取ID部分
             ContentResolver:當(dāng)外部應(yīng)用需要對ContentProvider中的數(shù)據(jù)進(jìn)行添加、刪除、修改和查詢操作時,可以使用 ContentResolver 類來完成,要獲取ContentResolver 對象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insert、delete、update、query方法,來操作數(shù)據(jù)。
            ㈤.數(shù)據(jù)庫存儲方式?
            數(shù)據(jù)庫存儲方式,最長用的是SQLite
            8. 如何啟用Service,如何停用Service
              ● 啟動方式和停止方式:
            ㈠.Context.startService() / Context.stopService();
            ㈡. Context.bindService() / Context.unbindService();
            9. 注冊廣播有幾種方式,這些方式有何優(yōu)缺點?請談?wù)凙ndroid引入廣播機制的用意。
              在android下,要想接受廣播信息,那么這個廣播接收器就得我們自己來實現(xiàn)了,我們可以繼承BroadcastReceiver,就可以有一個廣播接受器了。有個接受器還不夠,我們還得重寫B(tài)roadcastReceiver里面的onReceiver方法,當(dāng)來廣播的時候我們要干什么,這就要我們自己來實現(xiàn),不過我們可以搞一個信息防火墻。具體的代碼:
            public class SmsBroadCastReceiver extends BroadcastReceiver  
            {  
              public void onReceive(Context context, Intent intent)  
              {  
              Bundle bundle = intent.getExtras();  
              Object[] object = (Object[])bundle.get("pdus");  
              SmsMessage sms[]=new SmsMessage[object.length];  
              for(int i=0;i<object.length;i++)  
              {  
              sms[0] = SmsMessage.createFromPdu((byte[])object[i]);  
              Toast.makeText(context, "來自 "+sms[i].getDisplayOriginatingAddress()+" 的消息是:"+sms[i].getDisplayMessageBody(), Toast.LENGTH_SHORT).show();  
              }  
              //終止廣播,在這里我們可以稍微處理,根據(jù)用戶輸入的號碼可以實現(xiàn)短信防火墻。  
              abortBroadcast();  
              }  
               
            }  
            當(dāng)實現(xiàn)了廣播接收器,還要設(shè)置廣播接收器接收廣播信息的類型,這里是信息:android.provider.Telephony.SMS_RECEIVED
              我們就可以把廣播接收器注冊到系統(tǒng)里面,可以讓系統(tǒng)知道我們有個廣播接收器。這里有兩種,
            ? 一種是代碼動態(tài)注冊:
            //生成廣播處理  
            smsBroadCastReceiver = new SmsBroadCastReceiver();  
            //實例化過濾器并設(shè)置要過濾的廣播  
            IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); 

            //注冊廣播  
            BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver, intentFilter);  
            ? 一種是在AndroidManifest.xml中配置廣播
            <?xml version="1.0" encoding="utf-8"?>  
            <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="spl.broadCastReceiver"  
              android:versionCode="1"  
              android:versionName="1.0">  
              <application android:icon="@drawable/icon" android:label="@string/app_name">  
              <activity android:name=".BroadCastReceiverActivity"  
              android:label="@string/app_name">  
              <intent-filter>  
              <action android:name="android.intent.action.MAIN" />  
              <category android:name="android.intent.category.LAUNCHER" />  
              </intent-filter>  
              </activity>  
               
              <!--廣播注冊-->  
              <receiver android:name=".SmsBroadCastReceiver">  
              <intent-filter android:priority="20">  
              <action android:name="android.provider.Telephony.SMS_RECEIVED"/>  
              </intent-filter>  
              </receiver>  
               
              </application>  
               
              <uses-sdk android:minSdkVersion="7" />  
               
              <!-- 權(quán)限申請 -->  
              <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>  
               
            </manifest>  
              兩種注冊類型的區(qū)別是:
              1)第一種不是常駐型廣播,也就是說廣播跟隨程序的生命周期。
              2)第二種是常駐型,也就是說當(dāng)應(yīng)用程序關(guān)閉后,如果有信息廣播來,程序也會被系統(tǒng)調(diào)用自動運行
            請解釋下在單線程模型中Message、Handler、Message Queue、Looper之間的關(guān)系。
              2.2 Message Queue
              在單線程模型下,為了解決類似的問題,Android設(shè)計了一個Message Queue(消息隊列), 線程間可以通過該Message Queue并結(jié)合Handler和Looper組件進(jìn)行信息交換。下面將對它們進(jìn)行分別介紹:
            1. Message
              Message消息,理解為線程間交流的信息,處理數(shù)據(jù)后臺線程需要更新UI,則發(fā)送Message內(nèi)含一些數(shù)據(jù)給UI線程。
            2. Handler
              Handler處理者,是Message的主要處理者,負(fù)責(zé)Message的發(fā)送,Message內(nèi)容的執(zhí)行處理。后臺線程就是通過傳進(jìn)來的 Handler對象引用來sendMessage(Message)。而使用Handler,需要implement 該類的 handleMessage(Message)
            方法,它是處理這些Message的操作內(nèi)容,例如Update UI。通常需要子類化Handler來實現(xiàn)handleMessage方法。
            3. Message Queue
              Message Queue消息隊列,用來存放通過Handler發(fā)布的消息,按照先進(jìn)先出執(zhí)行。
              每個message queue都會有一個對應(yīng)的Handler。Handler會向message queue通過兩種方法發(fā)送消息:sendMessage或post。這兩種消息都會插在message queue隊尾并按先進(jìn)先出執(zhí)行。但通過這兩種方法發(fā)送的消息執(zhí)行的方式略有不同:通過sendMessage發(fā)送的是一個message對象,會被 Handler的handleMessage()函數(shù)處理;而通過post方法發(fā)送的是一個runnable對象,則會自己執(zhí)行。
            4. Looper
              Looper是每條線程里的Message Queue的管家。Android沒有Global的Message Queue,而Android會自動替主線程(UI線程)建立Message Queue,但在子線程里并沒有建立Message Queue。所以調(diào)用Looper.getMainLooper()得到的主線程的Looper不為NULL,但調(diào)用Looper.myLooper() 得到當(dāng)前線程的Looper就有可能為NULL。
              對于子線程使用Looper,API Doc提供了正確的使用方法:

              這個Message機制的大概流程:
              1. 在Looper.loop()方法運行開始后,循環(huán)地按照接收順序取出Message Queue里面的非NULL的Message。
              2. 一開始Message Queue里面的Message都是NULL的。當(dāng)Handler.sendMessage(Message)到Message Queue,該函數(shù)里面設(shè)置了那個Message對象的target屬性是當(dāng)前的Handler對象。隨后Looper取出了那個Message,則調(diào)用該Message的target指向的Hander的dispatchMessage函數(shù)對Message進(jìn)行處理。
              在dispatchMessage方法里,如何處理Message則由用戶指定,三個判斷,優(yōu)先級從高到低:
              1) Message里面的Callback,一個實現(xiàn)了Runnable接口的對象,其中run函數(shù)做處理工作;
              2) Handler里面的mCallback指向的一個實現(xiàn)了Callback接口的對象,由其handleMessage進(jìn)行處理;
              3) 處理消息Handler對象對應(yīng)的類繼承并實現(xiàn)了其中handleMessage函數(shù),通過這個實現(xiàn)的handleMessage函數(shù)處理消息。
              由此可見,我們實現(xiàn)的handleMessage方法是優(yōu)先級最低的!
              3. Handler處理完該Message (update UI) 后,Looper則設(shè)置該Message為NULL,以便回收!
              在網(wǎng)上有很多文章講述主線程和其他子線程如何交互,傳送信息,最終誰來執(zhí)行處理信息之類的,個人理解是最簡單的方法——判斷Handler對象里面的 Looper對象是屬于哪條線程的,則由該線程來執(zhí)行!
              1. 當(dāng)Handler對象的構(gòu)造函數(shù)的參數(shù)為空,則為當(dāng)前所在線程的Looper;
              2. Looper.getMainLooper()得到的是主線程的Looper對象,Looper.myLooper()得到的是當(dāng)前線程的Looper對象。

            11. AIDL的全稱是什么?如何工作?能處理哪些類型的數(shù)據(jù)?
              AIDL(AndRoid接口描述語言)是一種接口描述語言; 編譯器可以通過aidl文件生成一段代碼,通過預(yù)先定義的接口達(dá)到兩個進(jìn)程內(nèi)部通信進(jìn)程的目的. 如果需要在一個Activity中, 訪問另一個Service中的某個對象, 需要先將對象轉(zhuǎn)化成AIDL可識別的參數(shù)(可能是多個參數(shù)), 然后使用AIDL來傳遞這些參數(shù), 在消息的接收端, 使用這些參數(shù)組裝成自己需要的對象.
            AIDL的IPC的機制和COM或CORBA類似, 是基于接口的,但它是輕量級的。它使用代理類在客戶端和實現(xiàn)層間傳遞值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相關(guān)類.; 2. 調(diào)用aidl產(chǎn)生的class.
            AIDL的創(chuàng)建方法:
            AIDL語法很簡單,可以用來聲明一個帶一個或多個方法的接口,也可以傳遞參數(shù)和返回值。由于遠(yuǎn)程調(diào)用的需要, 這些參數(shù)和返回值并不是任何類型.
            下面是些AIDL支持的數(shù)據(jù)類型:
            1. 不需要import聲明的簡單Java編程語言類型(int,boolean等)
            2. String, CharSequence不需要特殊聲明 
            3. List, Map和Parcelables類型, 這些類型內(nèi)所包含的數(shù)據(jù)成員也只能是簡單數(shù)據(jù)類型, String等其他比支持的類型.
            12. 請解釋下Android程序運行時權(quán)限與文件系統(tǒng)權(quán)限的區(qū)別
              要區(qū)分apk運行時的擁有的權(quán)限與在文件系統(tǒng)上被訪問(讀寫執(zhí)行)的權(quán)限兩個概念。
              apk程序是運行在虛擬機上的,對應(yīng)的是Android獨特的權(quán)限機制,只有體現(xiàn)到文件系統(tǒng)上時才使用linux的權(quán)限設(shè)置
            (一)linux文件系統(tǒng)上的權(quán)限
            -rwxr-x--x system system 4156 2010-04-30 16:13 test.apk
              代表的是相應(yīng)的用戶/用戶組及其他人對此文件的訪問權(quán)限,與此文件運行起來具有的權(quán)限完全不相關(guān)。比如上面的例子只能說明system用戶擁有對此文件的讀寫執(zhí)行權(quán)限;system組的用戶對此文件擁有讀、執(zhí)行權(quán)限;其他人對此文件只具有執(zhí)行權(quán)限。
            而test.apk運行起來后可以干哪些事情,跟這個就不相關(guān)了。
            千萬不要看apk文件系統(tǒng)上屬于system/system用戶及用戶組,或者root/root用戶及用戶組,就認(rèn)為apk具有system或root權(quán)限
              (二)Android的權(quán)限規(guī)則
              (1)Android中的apk必須簽名
              這種簽名不是基于權(quán)威證書的,不會決定某個應(yīng)用允不允許安裝,而是一種自簽名證書。重要的是,android系統(tǒng)有的權(quán)限是基于簽名的。比如:system等級的權(quán)限有專門對應(yīng)的簽名,簽名不對,權(quán)限也就獲取不到。
            默認(rèn)生成的APK文件是debug簽名的。
            (2)基于UserID的進(jìn)程級別的安全機制
            大家都知道,進(jìn)程有獨立的地址空間,進(jìn)程與進(jìn)程間默認(rèn)是不能互相訪問的,是一種很可靠的保護(hù)機制。
            Android通過為每一個安裝在設(shè)備上的包(apk)分配唯一的linux userID來實現(xiàn),名稱為"app_"加一個數(shù)字,比如app_43
            不同的UserID,運行在不同的進(jìn)程,所以apk之間默認(rèn)便不能相互訪問。
            Android提供了如下的一種機制,可以使兩個apk打破前面講的這種壁壘。
            在AndroidManifest.xml中利用sharedUserId屬性給不同的package分配相同的userID,通過這樣做,兩個package可以被當(dāng)做同一個程序,
            系統(tǒng)會分配給兩個程序相同的UserID。當(dāng)然,基于安全考慮,兩個package需要有相同的簽名,否則沒有驗證也就沒有意義了。
            (這里補充一點:并不是說分配了同樣的UserID,兩程序就運行在同一進(jìn)程, 下面為PS指令摘取的,
            顯然,system、app_2分別對應(yīng)的兩個進(jìn)程的PID都不同,不知Android到底是怎樣實現(xiàn)它的機制的)
            User PID PPID
            system 953 883 187340 55052 ffffffff afe0cbcc S system_server
            app_2 1072 883 100264 19564 ffffffff afe0dcc4 S com.android.inputmethod.
            system 1083 883 111808 23192 ffffffff afe0dcc4 S android.process.omsservi
            app_2 1088 883 156464 45720 ffffffff afe0dcc4 S android.process.acore
            (3)默認(rèn)apk生成的數(shù)據(jù)對外是不可見的
            實現(xiàn)方法是:Android會為程序存儲的數(shù)據(jù)分配該程序的UserID。
            借助于Linux嚴(yán)格的文件系統(tǒng)訪問權(quán)限,便實現(xiàn)了apk之間不能相互訪問似有數(shù)據(jù)的機制。
            例:我的應(yīng)用創(chuàng)建的一個文件,默認(rèn)權(quán)限如下,可以看到只有UserID為app_21的程序才能讀寫該文件。
            -rw------- app_21 app_21 87650 2000-01-01 09:48 test.txt
            如何對外開放?
            <1> 使用MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE 標(biāo)記。
            When creating a new file with getSharedPreferences(String, int), openFileOutput(String, int), or openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory), you can use the MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE flags to allow any other package to read/write the file. When setting these flags, the file is still owned by your application, but its global read and/or write permissions have been set appropriately so any other application can see it.

            (4)AndroidManifest.xml中的顯式權(quán)限聲明
            Android默認(rèn)應(yīng)用是沒有任何權(quán)限去操作其他應(yīng)用或系統(tǒng)相關(guān)特性的,應(yīng)用在進(jìn)行某些操作時都需要顯式地去申請相應(yīng)的權(quán)限。
            一般以下動作時都需要申請相應(yīng)的權(quán)限:
            A particular permission may be enforced at a number of places during your program's operation: 
            • At the time of a call into the system, to prevent an application from executing certain functions.
            • When starting an activity, to prevent applications from launching activities of other applications.
            • Both sending and receiving broadcasts, to control who can receive your broadcast or who can send a broadcast to you.
            • When accessing and operating on a content provider.
            • Binding or starting a service.

            在應(yīng)用安裝的時候,package installer會檢測該應(yīng)用請求的權(quán)限,根據(jù)該應(yīng)用的簽名或者提示用戶來分配相應(yīng)的權(quán)限。
            在程序運行期間是不檢測權(quán)限的。如果安裝時權(quán)限獲取失敗,那執(zhí)行就會出錯,不會提示用戶權(quán)限不夠。
            大多數(shù)情況下,權(quán)限不足導(dǎo)致的失敗會引發(fā)一個 SecurityException, 會在系統(tǒng)log(system log)中有相關(guān)記錄。
            (5)權(quán)限繼承/UserID繼承
            當(dāng)我們遇到apk權(quán)限不足時,我們有時會考慮寫一個linux程序,然后由apk調(diào)用它去完成某個它沒有權(quán)限完成的事情,很遺憾,這種方法是行不通的。
            前面講過,android權(quán)限是經(jīng)營在進(jìn)程層面的,也就是說一個apk應(yīng)用啟動的子進(jìn)程的權(quán)限不可能超越其父進(jìn)程的權(quán)限(即apk的權(quán)限),
            即使單獨運行某個應(yīng)用有權(quán)限做某事,但如果它是由一個apk調(diào)用的,那權(quán)限就會被限制。
            實際上,android是通過給子進(jìn)程分配父進(jìn)程的UserID實現(xiàn)這一機制的。
            (三)常見權(quán)限不足問題分析

            首先要知道,普通apk程序是運行在非root、非system層級的,也就是說看要訪問的文件的權(quán)限時,看的是最后三位。
            另外,通過system/app安裝的apk的權(quán)限一般比直接安裝或adb install安裝的apk的權(quán)限要高一些。

            言歸正傳,運行一個android應(yīng)用程序過程中遇到權(quán)限不足,一般分為兩種情況:
            (1)Log中可明顯看到權(quán)限不足的提示。
            此種情況一般是AndroidManifest.xml中缺少相應(yīng)的權(quán)限設(shè)置,好好查找一番權(quán)限列表,應(yīng)該就可解決,是最易處理的情況。
            有時權(quán)限都加上了,但還是報權(quán)限不足,是什么情況呢?
            Android系統(tǒng)有一些API及權(quán)限是需要apk具有一定的等級才能運行的。
            比如 SystemClock.setCurrentTimeMillis()修改系統(tǒng)時間,WRITE_SECURE_SETTINGS權(quán)限好像都是需要有system級的權(quán)限才行。
            也就是說UserID是system.
            (2)Log里沒有報權(quán)限不足,而是一些其他Exception的提示,這也有可能是權(quán)限不足造成的。
            比如:我們常會想讀/寫一個配置文件或其他一些不是自己創(chuàng)建的文件,常會報java.io.FileNotFoundException錯誤。
            系統(tǒng)認(rèn)為比較重要的文件一般權(quán)限設(shè)置的也會比較嚴(yán)格,特別是一些很重要的(配置)文件或目錄。

            -r--r----- bluetooth bluetooth 935 2010-07-09 20:21 dbus.conf
            drwxrwx--x system system 2010-07-07 02:05 data 

            dbus.conf好像是藍(lán)牙的配置文件,從權(quán)限上來看,根本就不可能改動,非bluetooth用戶連讀的權(quán)利都沒有。
            /data目錄下存的是所有程序的私有數(shù)據(jù),默認(rèn)情況下android是不允許普通apk訪問/data目錄下內(nèi)容的,通過data目錄的權(quán)限設(shè)置可知,其他用戶沒有讀的權(quán)限。
            所以adb普通權(quán)限下在data目錄下敲ls命令,會得到opendir failed, Permission denied的錯誤,通過代碼file.listfiles()也無法獲得data目錄下的內(nèi)容。
            13. 系統(tǒng)上安裝了多種瀏覽器,能否指定某瀏覽器訪問指定頁面?請說明原由。
              如果在你的android系統(tǒng)上安裝了多種瀏覽器,能否指定某瀏覽器訪問指定頁面?答案當(dāng)然是:肯定的。
            問題的關(guān)鍵在于我們設(shè)置了class name,也就是我們想要跳轉(zhuǎn)的pakcage的activity。如果你想要跳轉(zhuǎn)到其它的瀏覽器,只需要修改一下這個函數(shù)就OK了。
              好,我們現(xiàn)在來讓剛剛的思路來指導(dǎo)我們的實踐。假如我們現(xiàn)在要直接啟動UC瀏覽器,那么我們該怎么做呢?讓我們step by step吧。

            1.下載UC apk:http://i-uc.net/read.php?2

            2. 用7zip解壓apk文件,得到classes.dex文件

            3.下載反編譯dex文件工具:http://nchc.dl.sourceforge.net/project/dedexer/dedexer/1.5/ddx1.5.jar(Dedexer 項目主頁: http://dedexer.sourceforge.net/)
            4.執(zhí)行命令:java -jar ddx1.5.jar -o -D -d c:\ c:\classes.dex
            5. 得到package name是:com.uc.browser,啟動的activity是:com.uc.browser.ActivityUpdate(補充:當(dāng)我在這里選擇采用ActivityBrowser的時候發(fā)覺權(quán)限不夠,報permiss denied 異常,而且也不是我們要的那個activity,幸運的是在第二次嘗試用ActivityUpdate,剛好能滿足要求)
            6.修改上面的代碼為intent.setClassName("com.uc.browser","com.uc.browser.ActivityUpdate");
            posted on 2011-12-06 16:38 life02 閱讀(880) 評論(0)  編輯 收藏 引用 所屬分類: android面試題
            亚洲人AV永久一区二区三区久久| 久久国产亚洲精品| 国内精品久久国产大陆| AV无码久久久久不卡蜜桃 | 国产高潮久久免费观看| 久久国产成人午夜aⅴ影院| 亚洲国产日韩欧美综合久久| 久久精品卫校国产小美女| 狠狠色丁香婷婷久久综合不卡| 久久精品亚洲福利| 久久久婷婷五月亚洲97号色| 久久se这里只有精品| 婷婷久久久亚洲欧洲日产国码AV | 人妻少妇精品久久| 99久久99久久精品免费看蜜桃| 精品久久久久久久久久中文字幕| 久久亚洲国产成人精品性色| 久久久人妻精品无码一区| 国产精品美女久久久| 中文字幕久久久久人妻| 亚洲精品成人久久久| 精品久久久久久无码中文野结衣| 久久天天躁狠狠躁夜夜躁2O2O | 精品久久久久久国产牛牛app| 亚洲∧v久久久无码精品| 亚洲精品国产综合久久一线| 国产成人精品久久亚洲| 99国产精品久久久久久久成人热| 久久久亚洲AV波多野结衣| 久久国产免费直播| 国产成人无码精品久久久久免费| 久久久久久久亚洲Av无码| 综合久久国产九一剧情麻豆| 国色天香久久久久久久小说| 久久久久久久久波多野高潮| 性做久久久久久久久久久| 久久久精品日本一区二区三区| 国产精品丝袜久久久久久不卡 | 精品久久久久久无码不卡| 亚洲国产综合久久天堂| 久久久久久久久久免免费精品 |