自定义一个界面来替换Android自带的Home界面

如果你要定制一个Android系统,你想用你自己的Launcher(Home)作主界面来替换Android自带的Home,而且不希望用户安装的Launcher来替换掉你的Launcher,应该如何来实现呢?
我们可以通过修改Framework层来实现这样的功能。

  1. 首先了解一下Android的启动过程。
    Android系统的启动先从Zygote开始启动,然后…(中间的过程就不说了)…一直到了SystemServer(framework)这个地方,看到这段代码:
    /**
  • This method is called from Zygote to initialize the system. This willcause the native
  • services (SurfaceFlinger, AudioFlinger, etc…) to be started. Afterthat it will call back
  • up into init2() to start the Android services.
    */
    native public static void init1(String[] args);
    public static void main(String[] args) {
    if (SamplingProfilerIntegration.isEnabled()) {
    SamplingProfilerIntegration.start();
    timer = new Timer();
    timer.schedule(new TimerTask() {
    @Override
    public void run() {
    SamplingProfilerIntegration.writeSnapshot(“system_server”);
    }
    }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
    }
    // The system server has to run all of the time, so it needs to be
    // as efficient as possible with its memory usage.
    VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
    System.loadLibrary(“android_servers”);
    init1(args);
    }
    public static final void init2() {
    Log.i(TAG, “Entered the Android system server!”);
    Thread thr = new ServerThread();
    thr.setName(“android.server.ServerThread”);
    thr.start();
    }
    }
    从SystemServer的main函数开始启动各种服务:
    首先启动init1,然后启动init2.从上面的注释可以看到:init1这个方法时被Zygote调用来初始化系统的,init1会启动native的服务如SurfaceFlinger,AudioFlinger等等,这些工作做完以后会回调init2来启动Android的service。
    这里我们主要来关注init2的过程。init2中启动ServerThread线程,ServerThread中启动了一系列的服务,比如这些:
    ActivityManagerService
    EntropyService
    PowerManagerService
    TelephonyRegistry
    PackageManagerService
    AccountManagerService
    BatteryService
    HardwareService
    Watchdog
    SensorService
    BluetoothService
    StatusBarService
    ClipboardService
    InputMethodManagerService
    NetStatService
    ConnectivityService
    AccessibilityManagerService
    NotificationManagerService
    MountService
    DeviceStorageMonitorService
    LocationManagerService
    SearchManagerService
    FallbackCheckinService
    WallpaperManagerService
    AudioService
    BackupManagerService
    AppWidgetService
    这些大大小小的服务起来以后,开始
    ((ActivityManagerService)ActivityManagerNative.getDefault()).systemReady()
    在systemReady后开始开始启动Launcher。在寻找Launcher的时候是根据HOME的filter(在Manifest中定义的<categoryandroid:name=“android.intent.category.HOME” />)来过滤。
    然后根据filter出来的HOME来启动,如果只有一个HOME,则启动这个HOME,如果用户自己装了HOME,那就会弹出来一个列表供用户选择。
    我们现在希望从这里弹出我们自己定制的Launcher,同时也不希望弹出选择HOME的界面,我们不希望用户修改我们的home,比如我们的home上放了好多广告,以及强制安装的程序,不希望用户把它干掉。
    我们可以通过这样来实现:
  1. 定义一个私有的filter选项,然后用这个选项来过滤HOME.
    一般情况下我们使用Manifest中定义的<categoryandroid:name="android.intent.category.HOME"来过滤的,我们现在增加一个私有的HOME_FIRST过滤。
    在Intent.java(frameworks/base/core/java/android/content/Intent.java)中添加两行代码
    //lixinso:添加CATEGORY_FS_HOME
    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
    public static final String CATEGORY_FS_HOME= “android.intent.category.FS_HOME”;
    3)修改和CATEGORY_HOME相关的所有的地方,都改成CATEGORY_FS_HOME,主要是framework中的这几个地方:使用grep命令查找要修改的地方:
    grep CATEGORY_HOME -l * -R
    将上述文件中和CATEGORY_HOME相关的所有的地方,都改成CATEGORY_FS_HOME。
  2. 写一个自己的Launcher.
    可以参考android sample中的Launcher,或者android源代码中的 /packages/apps/Launcher 来写。
    在Launcher中标记其是不是Launcher的最关键的代码时Manifest中的filter:android:name=“android.intent.category.HOME”
    现在我们定义了自己的filter,那么,我们在我们自己写的Launcher中将Manifest改为:
    <application android:process=“android.process.acore3"android:icon=”@drawable/icon"android:label="@string/app_name">


    <actionandroid:name=“android.intent.action.MAIN” />
    <categoryandroid:name=“android.intent.category. FS_HOME” />
    <categoryandroid:name=“android.intent.category.DEFAULT” />




    然后将编译好的apk放到方式fs100_root/system/app目录下。
    5)将Android自带的Launcher删除掉
    包括源代码(packages/apps/Launcher)和apk(/out/target/product/generic/system/app/Launcher.apk)。
  3. 重新编译Android
    做完这些工作,就可以重新编译Android了,我们可以编译修改过的几个相关的包,可以用mmm命令来编译部分的改动。这里需要这样编译:
    $ source build/envsetup.sh
    $ lunch
    $ mmm frameworks/base
    $ mmm frameworks/base/services/java
    $ mmm frameworks/policies/base/mid
    $ mmm frameworks/policies/base/phone
    重新启动开发板,从开发板上就可以看到启动的Launcher是我们自己的Launcher,不会出现默认的Launcher了,也不会出现选择界面。
    9)我们再验证一下,如果用户装上了一个其他的Launcher(Home)会怎么样。
    从网上找一个一般的Launcher或者自己写一个一般的Launcher装上去,重新启动,不会出现选择界面。
    按HOME键也不会出来两个HOME来选择。
    这样我们就牢牢控制了用户的桌面。
    只有我们自己定制的HOME才能装上。这对于定制Android设备的厂商很有用处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值