2025年4月

  1. 有需求在子进程中创建provider实例,需要添加android:multiprocess="true"或者直接指定android:process属性来指定进程
  2. 在主进程中,Provider 会在应用启动的时候自动初始化一次,创建实例,执行oncreate方法
  3. 系统不会自动在子进程中初始化 Provider,只有当子进程首次访问这个 Provider 时,系统才会在该进程中初始化一个新的 Provider 实例,只有创建实例时候才会执行oncreate方法
  4. 为了解决这个问题,可以主动初始化
public class ProviderUtils {
    public static void initializeProvider(Context context, ProviderInfo providerInfo) {
        try {
            // 通过 ContentResolver 触发 Provider 初始化
            Uri uri = Uri.parse("content://" + providerInfo.authority);
            ContentProviderClient client = context.getContentResolver()
                    .acquireContentProviderClient(uri);
            if (client != null) {
                // Provider 已初始化
                client.release();
            } else {
                // 尝试通过 call 方法触发初始化
                context.getContentResolver().call(
                    uri,
                    "init",
                    null,
                    null
                );
            }
        } catch (Exception e) {
            Log.e("ProviderUtils", "Failed to initialize provider: " + providerInfo.authority, e);
        }
    }

    // 初始化所有 Provider
    public static void initializeAllProviders(Context context) {
        List<ProviderInfo> providers = getAllProviders(context);
        for (ProviderInfo provider : providers) {
            initializeProvider(context, provider);
        }
    }
}

放在application oncreate或者其它合适的地方

1. 使用object

object ObjectTest {
    init {
        println("ObjectTest init")
    }
    fun test() {
        println("ObjectTest test")
    }
}

然后看看编译的字节码对应的java代码

public final class ObjectTest {
   @NotNull
   public static final ObjectTest INSTANCE = new ObjectTest();
   private ObjectTest() {
   }
   public final void test() {
      String var1 = "ObjectTest test";
      System.out.println(var1);
   }
   static {
      String var0 = "ObjectTest init";
      System.out.println(var0);
   }
}

可以看见是一个饿汉式的单例模式,线程安全。这里的ObjectTest init,被编译成了static静态代码块,会在类加载的时候执行。

2. 使用companion object

class SingletonManager private constructor() {
    init {
        println("SingletonManager init")
    }
    companion object {
        val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            SingletonManager()
        }
    }
}

编译的字节码对应的java代码

public final class SingletonManager {
    @NotNull
    public static final Companion Companion = new SingletonManager.Companion((DefaultConstructorMarker)null);
    @NotNull
    private static final Lazy instance$delegate;
    private SingletonManager() {
        String var1 = "SingletonManager init";
        System.out.println(var1);
    }
    public SingletonManager(DefaultConstructorMarker $constructor_marker) {
        this();
    }
    static {
        instance$delegate = LazyKt.lazy(LazyThreadSafetyMode.SYNCHRONIZED, (Function0)null.INSTANCE);
    }
    public static final class Companion {
        private Companion() {
        }
        @NotNull
        public final SingletonManager getInstance() {
            Lazy var1 = SingletonManager.instance$delegate;
            Object var2 = null;
            return (SingletonManager)var1.getValue();
        }
        public Companion(DefaultConstructorMarker $constructor_marker) {
            this();
        }
    }
}

可以看见是懒汉式的,通过lazy初始化的,线程是否安全,取决于LazyThreadSafetyMode参数,默认是SYNCHRONIZED是线程安全的

3. 双检锁/双重校验锁

class SingletonManager private constructor() {
    companion object {
        @Volatile
        private var instance: SingletonManager? = null
        fun getInstance(): SingletonManager =
            instance ?: synchronized(this) {
                instance ?: SingletonManager().also { instance = it }
            }
    }
}

和java的双重校验锁类似,懒汉,线程安全

4. 静态内部类

class SingletonManager private constructor() {
    init {
        println("ObjectTest init")
    }
    companion object {
        fun getInstance() = Holder.INSTANCE
    }
    private object Holder {
        val INSTANCE = SingletonManager()
    }
}

和java的静态内部类类似,懒汉,线程安全

5. 枚举 不详细介绍