主頁 > 移動端開發 > Android Context完全決議,你所不知道的Context的各種細節

Android Context完全決議,你所不知道的Context的各種細節

2020-09-14 11:14:22 移動端開發

前幾篇文章,我也是費勁心思寫了一個ListView系列的三部曲,雖然在內容上可以說是絕對的精華,但是很多朋友都表示看不懂,好吧,這個系列不僅是把大家給難倒了,也確實是把我給難倒了,之前為了寫瀑布流ListView的Demo就寫了大半個月的時間,那么本篇文章我們就講點輕松的東西,不去分析那么復雜的原始碼了,而是來談一談大家都熟知的Context,

Context相信所有的Android開發人員基本上每天都在接觸,因為它太常見了,但是這并不代表Context沒有什么東西好講的,實際上Context有太多小的細節并不被大家所關注,那么今天我們就來學習一下那些你所不知道的細節,

Context型別

我們知道,Android應用都是使用Java語言來撰寫的,那么大家可以思考一下,一個Android程式和一個Java程式,他們最大的區別在哪里?劃分界限又是什么呢?其實簡單點分析,Android程式不像Java程式一樣,隨便創建一個類,寫個main()方法就能跑了,而是要有一個完整的Android工程環境,在這個環境下,我們有像Activity、Service、BroadcastReceiver等系統組件,而這些組件并不是像一個普通的Java物件new一下就能創建實體的了,而是要有它們各自的背景關系環境,也就是我們這里討論的Context,可以這樣講,Context是維持Android程式中各組件能夠正常作業的一個核心功能類,

下面我們來看一下Context的繼承結構:

image

Context的繼承結構還是稍微有點復雜的,可以看到,直系子類有兩個,一個是ContextWrapper,一個是ContextImpl,那么從名字上就可以看出,ContextWrapper是背景關系功能的封裝類,而ContextImpl則是背景關系功能的實作類,而ContextWrapper又有三個直接的子類,ContextThemeWrapper、Service和Application,其中,ContextThemeWrapper是一個帶主題的封裝類,而它有一個直接子類就是Activity,

那么在這里我們至少看到了幾個所比較熟悉的面孔,Activity、Service、還有Application,由此,其實我們就已經可以得出結論了,Context一共有三種型別,分別是Application、Activity和Service,這三個類雖然分別各種承擔著不同的作用,但它們都屬于Context的一種,而它們具體Context的功能則是由ContextImpl類去實作的,

那么Context到底可以實作哪些功能呢?這個就實在是太多了,彈出Toast、啟動Activity、啟動Service、發送廣播、操作資料庫等等等等都需要用到Context,由于Context的具體能力是由ContextImpl類去實作的,因此在絕大多數場景下,Activity、Service和Application這三種型別的Context都是可以通用的,不過有幾種場景比較特殊,比如啟動Activity,還有彈出Dialog,,出于安全原因的考慮,Android是不允許Activity或Dialog憑空出現的,一個Activity的啟動必須要建立在另一個Activity的基礎之上,也就是以此形成的回傳堆疊,而Dialog則必須在一個Activity上面彈出(除非是System Alert型別的Dialog),因此在這種場景下,我們只能使用Activity型別的Context,否則將會出錯,

Context數量

那么一個應用程式中到底有多少個Context呢?其實根據上面的Context型別我們就已經可以得出答案了,Context一共有Application、Activity和Service三種型別,因此一個應用程式中Context數量的計算公式就可以這樣寫:

Context數量 = Activity數量 + Service數量 + 1

上面的1代表著Application的數量,因為一個應用程式中可以有多個Activity和多個Service,但是只能有一個Application,

Application Context的設計

基本上每一個應用程式都會有一個自己的Application,并讓它繼承自系統的Application類,然后在自己的Application類中去封裝一些通用的操作,其實這并不是Google所推薦的一種做法,因為這樣我們只是把Application當成了一個通用工具類來使用的,而實際上使用一個簡單的單例類也可以實作同樣的功能,但是根據我的觀察,有太多的專案都是這樣使用Application的,當然這種做法也并沒有什么副作用,只是說明還是有不少人對于Application理解的還有些欠缺,那么這里我們先來對Application的設計進行分析,講一些大家所不知道的細節,然后再看一下平時使用Application的問題,

首先新建一個MyApplication并讓它繼承自Application,然后在AndroidManifest.xml檔案中對MyApplication進行指定,如下所示:

<application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    ......
</application>

指定完成后,當我們的程式啟動時Android系統就會創建一個MyApplication的實體,如果這里不指定的話就會默認創建一個Application的實體,

public class MainActivity extends Activity {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		MyApplication myApp = (MyApplication) getApplication();
		Log.d("TAG", "getApplication is " + myApp);
	}
	
}

可以看到,代碼很簡單,只需要呼叫getApplication()方法就能拿到我們自定義的Application的實體了,列印結果如下所示:

image

那么除了getApplication()方法,其實還有一個getApplicationContext()方法,這兩個方法看上去好像有點關聯,那么它們的區別是什么呢?我們將代碼修改一下:

public class MainActivity extends Activity {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		MyApplication myApp = (MyApplication) getApplication();
		Log.d("TAG", "getApplication is " + myApp);
		Context appContext = getApplicationContext();
		Log.d("TAG", "getApplicationContext is " + appContext);
	}
	
}

同樣,我們把getApplicationContext()的結果列印了出來,現在重新運行代碼,結果如下圖所示:

image

咦?好像列印出的結果是一樣的呀,連后面的記憶體地址都是相同的,看來它們是同一個物件,其實這個結果也很好理解,因為前面已經說過了,Application本身就是一個Context,所以這里獲取getApplicationContext()得到的結果就是MyApplication本身的實體,

那么有的朋友可能就會問了,既然這兩個方法得到的結果都是相同的,那么Android為什么要提供兩個功能重復的方法呢?實際上這兩個方法在作用域上有比較大的區別,getApplication()方法的語意性非常強,一看就知道是用來獲取Application實體的,但是這個方法只有在Activity和Service中才能呼叫的到,那么也許在絕大多數情況下我們都是在Activity或者Service中使用Application的,但是如果在一些其它的場景,比如BroadcastReceiver中也想獲得Application的實體,這時就可以借助getApplicationContext()方法了,如下所示:

public class MyReceiver extends BroadcastReceiver {
 
	@Override
	public void onReceive(Context context, Intent intent) {
		MyApplication myApp = (MyApplication) context.getApplicationContext();
		Log.d("TAG", "myApp is " + myApp);
	}
 
}

也就是說,getApplicationContext()方法的作用域會更廣一些,任何一個Context的實體,只要呼叫getApplicationContext()方法都可以拿到我們的Application物件,

那么更加細心的朋友會發現,除了這兩個方法之外,其實還有一個getBaseContext()方法,這個baseContext又是什么東西呢?我們還是通過列印的方式來驗證一下:

image

哦?這次得到的是不同的物件了,getBaseContext()方法得到的是一個ContextImpl物件,這個ContextImpl是不是感覺有點似曾相識?回去看一下Context的繼承結構圖吧,ContextImpl正是背景關系功能的實作類,也就是說像Application、Activity這樣的類其實并不會去具體實作Context的功能,而僅僅是做了一層介面封裝而已,Context的具體功能都是由ContextImpl類去完成的,那么這樣的設計到底是怎么實作的呢?我們還是來看一下原始碼吧,因為Application、Activity、Service都是直接或間接繼承自ContextWrapper的,我們就直接看ContextWrapper的原始碼,如下所示:

/**
 * Proxying implementation of Context that simply delegates all of its calls to
 * another Context.  Can be subclassed to modify behavior without changing
 * the original Context.
 */
public class ContextWrapper extends Context {
    Context mBase;
    
    /**
     * Set the base context for this ContextWrapper.  All calls will then be
     * delegated to the base context.  Throws
     * IllegalStateException if a base context has already been set.
     * 
     * @param base The new base context for this wrapper.
     */
    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }
 
    /**
     * @return the base context as set by the constructor or setBaseContext
     */
    public Context getBaseContext() {
        return mBase;
    }
 
    @Override
    public AssetManager getAssets() {
        return mBase.getAssets();
    }
 
    @Override
    public Resources getResources() {
        return mBase.getResources();
    }
 
    @Override
    public ContentResolver getContentResolver() {
        return mBase.getContentResolver();
    }
 
    @Override
    public Looper getMainLooper() {
        return mBase.getMainLooper();
    }
    
    @Override
    public Context getApplicationContext() {
        return mBase.getApplicationContext();
    }
 
    @Override
    public String getPackageName() {
        return mBase.getPackageName();
    }
 
    @Override
    public void startActivity(Intent intent) {
        mBase.startActivity(intent);
    }
    
    @Override
    public void sendBroadcast(Intent intent) {
        mBase.sendBroadcast(intent);
    }
 
    @Override
    public Intent registerReceiver(
        BroadcastReceiver receiver, IntentFilter filter) {
        return mBase.registerReceiver(receiver, filter);
    }
 
    @Override
    public void unregisterReceiver(BroadcastReceiver receiver) {
        mBase.unregisterReceiver(receiver);
    }
 
    @Override
    public ComponentName startService(Intent service) {
        return mBase.startService(service);
    }
 
    @Override
    public boolean stopService(Intent name) {
        return mBase.stopService(name);
    }
 
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        return mBase.bindService(service, conn, flags);
    }
 
    @Override
    public void unbindService(ServiceConnection conn) {
        mBase.unbindService(conn);
    }
 
    @Override
    public Object getSystemService(String name) {
        return mBase.getSystemService(name);
    }
 
    ......
}

由于ContextWrapper中的方法還是非常多的,我就進行了一些篩選,只貼出來了部分方法,那么上面的這些方法相信大家都是非常熟悉的,getResources()、getPackageName()、getSystemService()等等都是我們經常要用到的方法,那么所有這些方法的實作又是什么樣的呢?其實所有ContextWrapper中方法的實作都非常統一,就是呼叫了mBase物件中對應當前方法名的方法,

那么這個mBase物件又是什么呢?我們來看第16行的attachBaseContext()方法,這個方法中傳入了一個base引數,并把這個引數賦值給了mBase物件,而attachBaseContext()方法其實是由系統來呼叫的,它會把ContextImpl物件作為引數傳遞到attachBaseContext()方法當中,從而賦值給mBase物件,之后ContextWrapper中的所有方法其實都是通過這種委托的機制交由ContextImpl去具體實作的,所以說ContextImpl是背景關系功能的實作類是非常準確的,

那么另外再看一下我們剛剛列印的getBaseContext()方法,在第26行,這個方法只有一行代碼,就是回傳了mBase物件而已,而mBase物件其實就是ContextImpl物件,因此剛才的列印結果也得到了印證,

使用Application的問題

雖說Application的用法確實非常簡單,但是我們平時的開發作業當中也著實存在著不少Application誤用的場景,那么今天就來看一看有哪些比較容易犯錯的地方是我們應該注意的,

Application是Context的其中一種型別,那么是否就意味著,只要是Application的實體,就能隨時使用Context的各種方法呢?我們來做個實驗試一下就知道了:

public class MyApplication extends Application {
	
	public MyApplication() {
		String packageName = getPackageName();
		Log.d("TAG", "package name is " + packageName);
	}
	
}

這是一個非常簡單的自定義Application,我們在MyApplication的構造方法當中獲取了當前應用程式的包名,并列印出來,獲取包名使用了getPackageName()方法,這個方法就是由Context提供的,那么上面的代碼能正常運行嗎?跑一下就知道了,你將會看到如下所示的結果:

image

應用程式一啟動就立刻崩潰了,報的是一個空指標例外,看起來好像挺簡單的一段代碼,怎么就會成空指標了呢?但是如果你嘗試把代碼改成下面的寫法,就會發現一切正常了:

public class MyApplication extends Application {
	
	@Override
	public void onCreate() {
		super.onCreate();
		String packageName = getPackageName();
		Log.d("TAG", "package name is " + packageName);
	}
	
}

運行結果如下所示:

image

在構造方法中呼叫Context的方法就會崩潰,在onCreate()方法中呼叫Context的方法就一切正常,那么這兩個方法之間到底發生了什么事情呢?我們重新回顧一下ContextWrapper類的原始碼,ContextWrapper中有一個attachBaseContext()方法,這個方法會將傳入的一個Context引數賦值給mBase物件,之后mBase物件就有值了,而我們又知道,所有Context的方法都是呼叫這個mBase物件的同名方法,那么也就是說如果在mBase物件還沒賦值的情況下就去呼叫Context中的任何一個方法時,就會出現空指標例外,上面的代碼就是這種情況,Application中方法的執行順序如下圖所示:

image

Application中在onCreate()方法里去初始化各種全域的變數資料是一種比較推薦的做法,但是如果你想把初始化的時間點提前到極致,也可以去重寫attachBaseContext()方法,如下所示:

public class MyApplication extends Application {
	
	@Override
	protected void attachBaseContext(Context base) {
		// 在這里呼叫Context的方法會崩潰
		super.attachBaseContext(base);
		// 在這里可以正常呼叫Context的方法
	}
	
}

以上是我們平時在使用Application時需要注意的一個點,下面再來介紹另外一種非常普遍的Application誤用情況,

其實Android官方并不太推薦我們使用自定義的Application,基本上只有需要做一些全域初始化的時候可能才需要用到自定義Application,官方檔案描述如下:

image

但是就我的觀察而言,現在自定義Application的使用情況基本上可以達到100%了,也就是我們平時自己寫測驗demo的時候可能不會使用,正式的專案幾乎全部都會使用自定義Application,可是使用歸使用,有不少專案對自定義Application的用法并不到位,正如官方檔案中所表述的一樣,多數專案只是把自定義Application當成了一個通用工具類,而這個功能并不需要借助Application來實作,使用單例可能是一種更加標準的方式,

不過自定義Application也并沒有什么副作用,它和單例模式二選一都可以實作同樣的功能,但是我見過有一些專案,會把自定義Application和單例模式混合到一起使用,這就讓人大跌眼鏡了,一個非常典型的例子如下所示:

public class MyApplication extends Application {
	
	private static MyApplication app;
	
	public static MyApplication getInstance() {
		if (app == null) {
			app = new MyApplication();
		}
		return app;
	}
	
}

就像單例模式一樣,這里提供了一個getInstance()方法,用于獲取MyApplication的實體,有了這個實體之后,就可以呼叫MyApplication中的各種工具方法了,

但是這種寫法對嗎?這種寫法是大錯特錯!因為我們知道Application是屬于系統組件,系統組件的實體是要由系統來去創建的,如果這里我們自己去new一個MyApplication的實體,它就只是一個普通的Java物件而已,而不具備任何Context的能力,有很多人向我反饋使用 LitePal 時發生了空指標錯誤其實都是由于這個原因,因為你提供給LitePal的只是一個普通的Java物件,它無法通過這個物件來進行Context操作,

那么如果真的想要提供一個獲取MyApplication實體的方法,比較標準的寫法又是什么樣的呢?其實這里我們只需謹記一點,Application全域只有一個,它本身就已經是單例了,無需再用單例模式去為它做多重實體保護了,代碼如下所示:

public class MyApplication extends Application {
	
	private static MyApplication app;
	
	public static MyApplication getInstance() {
		return app;
	}
	
	@Override
	public void onCreate() {
		super.onCreate();
		app = this;
	}
	
}

getInstance()方法可以照常提供,但是里面不要做任何邏輯判斷,直接回傳app物件就可以了,而app物件又是什么呢?在onCreate()方法中我們將app物件賦值成this,this就是當前Application的實體,那么app也就是當前Application的實體了,

好了,關于Context的介紹就到這里吧,內容還是比較簡單易懂的,希望大家通過這篇文章可以理解Context更多的細節,并且不要去犯使用Context時的一些低級錯誤,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/34309.html

標籤:Android

上一篇:Android Studio 學習筆記(三):簡單控制元件及實體

下一篇:Android開發當中ListView的使用

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more