天天看點

android各版本相容問題彙總在開發過程中,遇到過各種各樣的代碼相容問題,有些問題真的是讓人頭大。這裡做一個記錄整理,各位網友有更多的相容問題,歡迎留言,我好補充下來,給更多的網友做一個彙總,謝謝!該部落格持續更新!

在開發過程中,遇到過各種各樣的代碼相容問題,有些問題真的是讓人頭大。

這裡做一個記錄整理,各位網友有更多的相容問題,歡迎留言,我好補充下來,給更多的網友做一個彙總,謝謝!

該部落格持續更新!

1. android Q(10.0)無法擷取到剪貼闆的内容

官方連結:https://developer.android.com/about/versions/10/privacy/changes?hl=zh-cn

android各版本相容問題彙總在開發過程中,遇到過各種各樣的代碼相容問題,有些問題真的是讓人頭大。這裡做一個記錄整理,各位網友有更多的相容問題,歡迎留言,我好補充下來,給更多的網友做一個彙總,謝謝!該部落格持續更新!

國内大家都會用搜狗、QQ這類第三方輸入法,是以預設輸入法就不用想了。目前正處于焦點的應用,經測試,在android 10.0以上的手機,從第三方應用複制回來之後,也會走onResume方法,但是直接在onResume方法擷取剪貼闆内容,就會得到空。那麼按照官方的說明,我們應該是要擷取應用的焦點,遺憾的是,搜遍文檔,也沒有看到系統提供的獲得焦點的監聽,是以這裡建議大家在onResume方法的最後,做一個延遲加載來擷取剪貼闆的内容,至于延遲的時間,取決于布局的複雜程度(畢竟要布局加載完成,才能了解為應用獲得了焦點),我這裡是将時間設定為1秒。

Handler().postDelayed({
                getClipboardContent() //在這裡寫了個方法擷取剪貼闆的内容
            },1000)
           

2.android 8.0 以上版本開啟service閃退

官方連結:https://developer.android.com/about/versions/oreo/android-8.0-changes.html#back-all

android各版本相容問題彙總在開發過程中,遇到過各種各樣的代碼相容問題,有些問題真的是讓人頭大。這裡做一個記錄整理,各位網友有更多的相容問題,歡迎留言,我好補充下來,給更多的網友做一個彙總,謝謝!該部落格持續更新!

崩潰日志如下:

android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground() at 
android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220) at 
android.os.Handler.dispatchMessage(Handler.java:109) at 
android.os.Looper.loop(Looper.java:166) at 
android.app.ActivityThread.main(ActivityThread.java:7555) at 
java.lang.reflect.Method.invoke(Native Method) at 
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469) at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)
           

解決辦法:

//啟動服務的時候判斷一下版本
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            startForegroundService(Intent(this,StepService::class.java))
        }else {
            startService(Intent(this, StepService::class.java))
        }
           
class StepService : Service() {

    override fun onCreate() {
        super.onCreate()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        //這裡判斷一下版本,8.0以後的,要建立一個通知
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            createNotificationChannel()
        }
        return super.onStartCommand(intent, flags, startId)
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel(){
        var mNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        var id = "這裡填包名"
        var name = "xxx"
        var description = "xxxxxx"
        var importance = NotificationManager.IMPORTANCE_DEFAULT
        var mChannel = NotificationChannel(id,name,importance)
        mChannel.description = description
        mNotificationManager.createNotificationChannel(mChannel)

        var intent = Intent(this, WebActivity::class.java) //這裡是點選這個通知去哪裡
        intent.putExtra("url", Contans.walkMoney)
        intent.putExtra("id","")
        intent.putExtra("icon","")
        intent.putExtra("name","")
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
        var pi = PendingIntent.getActivity(this,0,intent,0)

        var notification = Notification.Builder(this).setContentTitle("xxx")
             .setContentText("xxxxxx").setSmallIcon(R.mipmap.ic_launcher).setChannelId(id)
                .setContentIntent(pi).setAutoCancel(true)
                .build()
        startForeground(1,notification)
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
}
           

NOTICE: 經實際測試,并非所有8.0以上的手機都會閃退,即部分8.0以上的手機,不調用startForegroundService 也不會閃退; 同時做了上述修正代碼之後,在一些8.0以上的手機,也并不會出現通知,猜測和國内廠商修改android源碼有關

3.剪貼闆ClipData閃退

崩潰日志:

java.lang.SecurityException: tp.defen.guard from uid 10935 not allowed to perform READ_CLIPBOARD 
at android.os.Parcel.createException(Parcel.java:2087) at 
android.os.Parcel.readException(Parcel.java:2055) at 
android.os.Parcel.readException(Parcel.java:2003) at 
android.content.IClipboard$Stub$Proxy.setPrimaryClip(IClipboard.java:293) at 
android.content.ClipboardManager.setPrimaryClip(ClipboardManager.java:106) at 
//這裡因為隐私問題,屏蔽了對應的包名的崩潰日志
android.view.View.performClick(View.java:7275) at 
android.view.View.performClickInternal(View.java:7227) at 
android.view.View.access$3800(View.java:829) at 
android.view.View$PerformClick.run(View.java:27920) at 
android.os.Handler.handleCallback(Handler.java:883) at 
android.os.Handler.dispatchMessage(Handler.java:100) at 
android.os.Looper.loop(Looper.java:238) at 
android.app.ActivityThread.main(ActivityThread.j$
           

根據崩潰日志,我去查了一下 tp.defen.guard這個app,名稱叫 “強力殺毒衛士”,這個app可以禁止應用使用剪貼闆,是以,無奈,隻能在代碼中加入try catch解決問題

try {
                                val mClipData: ClipData = ClipData.newPlainText("Label", "")
                                cm.primaryClip = mClipData
                            }catch (e:Exception){}
           

4.java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference

崩潰日志

Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.binfenli.quanyika/cn.binfenli.quanyika.SplashActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2884)
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2945)
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at android.app.ActivityThread.-wrap12(ActivityThread.java)
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1655)
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at android.os.Handler.dispatchMessage(Handler.java:102)
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at android.os.Looper.loop(Looper.java:154)
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at android.app.ActivityThread.main(ActivityThread.java:6457)
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at java.lang.reflect.Method.invoke(Native Method)
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1000)
Error
	
06-04 10:17:14.414
	
18538
	
AndroidRuntime
	
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:890) 

Found activity ActivityRecord{26729e8 u0 (這裡是包名)/.(崩潰的activity名) t445 f} in proc activity list using null instead of expected ProcessRecord{bcb3d65 18538:(包名)/u0a955} 
           

這個崩潰日志真是讓人頭痛,沒有任何有用的資訊,最下面一行的崩潰資訊,是打開APP的啟動頁,也就是一打開APP就崩潰了,而且沒有指向任何一行代碼。在更下面的日志裡面,找到一行指向的代碼,是空指針,指向的是自定義的BaseActivity的OnCreate方法的

super.onCreate(savedInstanceState)這行代碼
           

我簡直吐了,這行代碼怎麼可能會引發空指針呢。

這裡特别說明一下,筆者遇到這個問題,來自于第三方平台的崩潰監測,崩潰的手機:魅族

型号:meizu 16x , android版本:7.1.1

由于公司沒有這台手機,雲真機也沒有這台手機,是以先找了一些android版本7.1.1的手機測試,測試了小米、華為、oppo、vivo的android 7.1.1的手機,均正常。最後終于在騰訊的wetest找到一台型号叫meizu 15的android 7.1.1的手機,果然,打開就閃退,隻能說:垃圾魅族!!!

最後沒辦法呀,隻能從頭找原因

1.先是寫了個testactivity,不再繼承BaseActivity,而是繼承AppCompatActivity,界面還是使用當時閃退的啟動頁的xml,打開,閃退,說明并不是BaseActivity的問題

2. 重新寫一個xml,裡面就一個textview,顯示hello world,testactivity用這個布局,打開,閃退,說明也不是啟動頁的布局的問題

3.去除AndroidManifest.xml裡面application的android:name,不再使用自定義的Application,打開,正常!!!

找到了原因,就開始在Application裡面找原因,最後終于找到

companion object{

private var instances = MyApplication()

}
           

居然是這行代碼導緻的錯誤,難道是不允許在這裡指派一個對象?于是改成這樣

private var instances:MyApplication? = null
           

在Application的OnCreate方法裡面指派

override fun onCreate() {
        super.onCreate()
         instances=this
}
           

問題解決,該問題目前筆者所遭遇的,隻出現在魅族手機,android 7.1.1的系統

5.java.lang.RuntimeException: Using WebView from more than one process at once with the same data directory is not supported.

錯誤日志

java.lang.RuntimeException: Using WebView from more than one process at once with the same 
data directory is not supported. https://crbug.com/558377 at 
org.chromium.android_webview.AwBrowserProcess.b(PG:11) at D5.m(PG:33) at C5.run(PG:2) at 
org.chromium.base.task.TaskRunnerImpl.g(PG:11) at Xs.run(Unknown Source:2) at 
android.os.Handler.handleCallback(Handler.java:883) at 
android.os.Handler.dispatchMessage(Handler.java:100) at 
android.os.Looper.loop(Looper.java:238) at 
android.app.ActivityThread.main(ActivityThread.java:7827) at 
java.lang.reflect.Method.invoke(Native Method) at 
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at
 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
           

這個錯誤發生在代碼設定的targetSdkVersion >=28并且手機是9.0以上的機器,是官方android P(9.0)的行為變更,不允許多程序使用同一目錄webview

解決辦法:在app的application類OnCreate方法中加入代碼

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            val processName = getProcessName()
            if (!"應用包名".equals(processName)) {
                WebView.setDataDirectorySuffix(processName)
            }
        }
           

6.部分手機(android 10.0以上系統)無法拉起微信小程式

在測試的過程中,被回報部分手機無法拉起微信小程式,網上找資料的時候,找到如下資料:

華為Android 10手機微信小程式無法調起的問題解決辦法 - 程式員大學營

說的有兩點問題:

1. 檢查微信的懸浮窗權限是否開啟

2. 檢查微信是否有顯示在其他應用上層的權限

經檢查,拉不起微信小程式的手機,的确是沒有開啟相應的權限(不是每台手機都有上述兩個權限,筆者的華為mate30是隻有2的權限),開啟權限之後,是能正常拉起小程式了。但這不能成為解決方案,因為我們不能引導使用者去做這個操作,于是經過測試,在拉起小程式的地方,先拉起微信,就可以了。

try {
                if(api!!.isWXAppInstalled){ //這個api是微信注冊的傳回,對象是IWXAPI
                    api!!.openWXApp() //判斷是否有安裝微信,有的話先拉起微信
                }
                //然後再拉起小程式
                var obj = JSONObject(json)
                var req = WXLaunchMiniProgram.Req()
                req.userName = obj.optString("userName")
                req.path = obj.optString("path")
                req.miniprogramType = WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE
                api!!.sendReq(req)
            }catch (e:Exception){}
           

7.微信小程式左上角的傳回按鍵或者自定義按鈕調用傳回事件,無法傳回至APP,并且導緻APP主程序被殺死

在第6點,APP拉起小程式之後,在對接到某個第三方的小程式時,發現對方的小程式和其它小程式不一樣。它自定義了頭部導航,左上角不是回到首頁的圖示,而是傳回按鍵,在點選該按鍵時,無反應,但神奇的發現APP的程序不見了。

解決方案:AndroidManifest.xml檔案中,找到 WXEntryActivity,添加啟動模式

android:launchMode="singleTask"      

其它任何模式都不行,必須是singleTask,具體原因暫不清楚