这几天,项目中有个新需求,需要按照模块添加不同的快捷方式到桌面上,从而方便用户的使用。特意进行了研究并分析了下58上面桌面快捷方式的实现。

首先多个shortcut的实现:

<activity            android:name="com.soyoungboy.android.demo.MainActivity"            android:configChanges="keyboardHidden|orientation"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <!-- 瀑布流 -->        <activity            android:name="com.soyoungboy.android.demo.pinterest.PinterestActivity"            android:icon="@drawable/sinkingview_charming"            android:launchMode="singleInstance"            android:process=":process.sub"            android:theme="@android:style/Theme.Light.NoTitleBar" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />            </intent-filter>        </activity>

重点是这里:

android:icon="@drawable/sinkingview_charming"
android:launchMode="singleInstance" -->必须这么写
android:process=":process.sub"--->指定新的进程给对应的activity

<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>

也可指定android:icon来对应这个Activity对应的快捷方式图标。

如果有<categoryandroid:name="android.intent.category.LAUNCHER"/>,那么快捷方式将在启动时创建,也可不设置这行,通过代码去实现。

ShortCutUtils.java

import java.util.List;import android.content.Context;import android.content.Intent;import android.content.Intent.ShortcutIconResource;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.content.pm.PackageManager.NameNotFoundException;import android.content.pm.ProviderInfo;import android.database.Cursor;import android.net.Uri;import android.text.TextUtils;import android.util.Log;public class ShortCutUtils {    /**     * 快捷方式添加的action     */    private final static String SHORTCUT_ADD_ACTION = "com.android.launcher.action.INSTALL_SHORTCUT";    /**     * 快捷方式删除的action     */    private final static String SHORTCUT_DEL_ACTION = "com.android.launcher.action.UNINSTALL_SHORTCUT";    /**     * 读取数据库需要的权限     */    private final static String READ_SETTINGS_PERMISSION = "com.android.launcher.permission.READ_SETTINGS";    /**     * 添加快捷方式到桌面,添加快捷方式需要添加用户权限 <uses-permission     * android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />     *      * <br>     * <b> 当应用内部需要多个快捷方式时 :</b><br>     * android:taskAffinity="" <br>     * action android:name="android.intent.action.MAIN"<br>     * android:launchMode="singleTask"     *      * @param context     * @param className     * @param resourceId 快捷方式的图标     * @param appName 快捷方式的名字     * @param extra     */    public static void addShortCut(Context context, String className,            int resourceId, String appName, String extra) {        Intent shortCutIntent = new Intent(SHORTCUT_ADD_ACTION);        try {            if (appName == null) {                // 获取当前应用名称                appName = obtatinAppName(context);            }        } catch (NameNotFoundException e) {            Log.e("ShortCutUtils==>addShortCut",                    "NameNotFoundException :" + e.toString());        }        // 添加快捷方式的名字        shortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, appName);        // 不允许重复添加        shortCutIntent.putExtra("duplicate", false);        if (className == null) {            className = context.getClass().getName();        }        // 在里面的intent添加参数        shortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,                new Intent().setClassName(context.getPackageName(), className)                        .putExtra("ShortCutExtra", extra));        // 添加快捷方式的图标        ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext(                context, resourceId);        shortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);        context.sendBroadcast(shortCutIntent);    }    /**     * 删除桌面上的快捷方式,需要添加权限 <uses-permission     * android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />     *      * @param context     * @param className     * @param appName     */    public static void delShortcut(Context context, String className,            String appName) {        Intent shortcut = new Intent(SHORTCUT_DEL_ACTION);        try {            if (appName == null) {                // 获取当前应用名称                appName = obtatinAppName(context);            }        } catch (NameNotFoundException e) {            Log.e("ShortCutUtils==>delShortcut",                    "NameNotFoundException :" + e.toString());        }        // 快捷方式名称        shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, appName);        if (className == null) {            className = context.getClass().getName();        }        shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(                Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)                .setClassName(context.getPackageName(), className));        context.sendBroadcast(shortcut);    }    /**     * 判断桌面上是否有快捷方式,调用此方法需要添加权限 <uses-permission     * android:name="com.android.launcher.permission.READ_SETTINGS" />     *      * @param context     * @return     * @throws NameNotFoundException     */    public static boolean hasShortcut(Context context, String appName) {        String AUTHORITY = getAuthorityFromPermission(context,                READ_SETTINGS_PERMISSION);        if (AUTHORITY == null) {            return false;        }        Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY                + "/favorites?notify=true");        try {            if (appName == null) {                // 获取当前应用名称                appName = obtatinAppName(context);            }        } catch (NameNotFoundException e) {            Log.e("ShortCutUtils==>hasShortcut",                    "NameNotFoundException :" + e.toString());        }        Cursor c = context.getContentResolver().query(CONTENT_URI,                new String[] { "title" }, "title=?", new String[] { appName },                null);        if (c != null && c.getCount() > 0) {            return true;        }        return false;    }    /**     * android系统桌面的基本信息由一个launcher.db的Sqlite数据库管理,里面有三张表     * 其中一张表就是favorites。这个db文件一般放在data     * /data/com.android.launcher(launcher2)文件的databases下 但是对于不同的rom会放在不同的地方     * 例如MIUI放在data/data/com.miui.home/databases下面     * htc放在data/data/com.htc.launcher/databases下面     *      * @param context     * @param permission     *            读取设置的权限 READ_SETTINGS_PERMISSION     * @return     */    private static String getAuthorityFromPermission(Context context,            String permission) {        if (TextUtils.isEmpty(permission)) {            return null;        }        List<PackageInfo> packs = context.getPackageManager()                .getInstalledPackages(PackageManager.GET_PROVIDERS);        if (packs == null) {            return null;        }        for (PackageInfo pack : packs) {            ProviderInfo[] providers = pack.providers;            if (providers != null) {                for (ProviderInfo provider : providers) {                    if (permission.equals(provider.readPermission)                            || permission.equals(provider.writePermission)) {                        return provider.authority;                    }                }            }        }        return null;    }    /**     * 获取应用的名称     *      * @param context     * @return     * @throws NameNotFoundException     */    private static String obtatinAppName(Context context)            throws NameNotFoundException {        PackageManager packageManager = context.getPackageManager();        return packageManager.getApplicationLabel(                packageManager.getApplicationInfo(context.getPackageName(),                        PackageManager.GET_META_DATA)).toString();    }}

Activity中创建快捷方式:
这是Activity oncreate()里面的代码:

if (!ShortCutUtils.hasShortcut(getApplicationContext(), "瀑布流")) {            ShortCutUtils.addShortCut(getApplicationContext(),                    "com.soyoungboy.android.demo.pinterest.PinterestActivity2",                    R.drawable.sinkingview_charming, "瀑布流", "PinterestActivity2");        }


这样就会针对这个Activity创建快捷方式,如果点击启动我们设置在ShortCutIntent中对应的Activity的界面。从而实现多icon,多个执行入口的功能。


然后我们分析下58同城骚当的快捷方式,当然在没看到内部实现远离之前,我是这么认为的。

首先看下界面:

android 多个shortCut快捷方式实现以及对58同城快捷方式的实现思路的研究

点击后:

android 多个shortCut快捷方式实现以及对58同城快捷方式的实现思路的研究

后续就是进入对应模块界面了,我就不截图了。

然后反编译下代码,看下怎么实现的。

配置文件里面有如下内容:

  <activity android:theme="@style/DialogActivity" android:name="com.wuba.plugins.ThirdFolderActivity" android:taskAffinity="com.wuba.affinity_third_folder" android:screenOrientation="portrait" android:configChanges="locale|keyboardHidden">            <intent-filter>                <action android:name="android.intent.action.VIEW" />                <action android:name="android.intent.action.MAIN" />            </intent-filter>        </activity>

然后分析LauchActivity的java文件:

<activity android:label="@string/app_name" android:name="com.wuba.activity.launch.LaunchActivity" android:screenOrientation="portrait" android:configChanges="locale|keyboardHidden">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>

由上面看出是程序入口:
LauchActivity反编译后的代码片段:

package com.wuba.activity.launch;import android.app.Activity;import android.app.Dialog;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.SharedPreferences;import android.graphics.Bitmap;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.text.TextUtils;import android.view.View;import android.view.ViewGroup;import android.view.ViewStub;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import com.networkbench.agent.impl.NBSAppAgent;import com.wuba.actionlog.ActionLogObservService;import com.wuba.actionlog.OpenClientIntentService;import com.wuba.activity.home.a.c.a;import com.wuba.activity.recruit.RecruitCateActivity;import com.wuba.activity.webactivity.CategoryListActivity;import com.wuba.activity.webactivity.GroupBuyHomeActivity;import com.wuba.android.lib.util.commons.f;import com.wuba.android.lib.util.commons.h;import com.wuba.android.lib.util.commons.j;import com.wuba.android.lib.util.commons.k;import com.wuba.android.lib.util.commons.m;import com.wuba.application.WubaHybridApplication;import com.wuba.f.a.a;import com.wuba.f.a.g;import com.wuba.f.a.i;import com.wuba.f.a.l;import com.wuba.fragment.InfoListFragmentActivity;import com.wuba.frame.parse.beans.au;import com.wuba.frame.parse.beans.au.a;import com.wuba.home.HomeActivity;import com.wuba.model.bw;import com.wuba.plugins.weather.WeatherDetailActivity;import com.wuba.utils.at;import com.wuba.utils.bc;import com.wuba.utils.bf;import com.wuba.utils.r;import com.wuba.views.bm;import com.wuba.views.bm.a;import java.io.File;import java.io.IOException;import java.util.HashMap;import java.util.Iterator;import java.util.Map.Entry;import java.util.Set;import java.util.regex.Matcher;import java.util.regex.Pattern;public class LaunchActivity extends com.wuba.activity.a{  public static boolean g;  private static final String h = h.a(LaunchActivity.class);  boolean b = false;  public ImageView c;  public TextView d;  public boolean e = true;  public boolean f;  private Thread i;  private Bitmap j;  private String k;  private Handler l = new a(this);  private Runnable m = new c(this);  static  {    g = false;  }  private void c()  {    if ((this.j != null) && (!this.j.isRecycled()))    {      this.j.recycle();      this.j = null;    }  }  private static String d(String paramString)  {    if ((!TextUtils.isEmpty(paramString)) && (paramString.startsWith("<font")))      try      {        Matcher localMatcher = Pattern.compile("size=\\d+").matcher(paramString);        if (localMatcher.find())        {          String str1 = localMatcher.group();          String str2 = str1.substring(1 + str1.indexOf("="));          return str2;        }      }      catch (Exception localException)      {        return "24";      }    return "24";  }  private void d()  {    String str1;    if (!this.b)    {      this.b = true;      if (bf.c(this) == 1)      {        str1 = bf.b(this);        if (!TextUtils.isEmpty(str1))          bf.n(this, "");      }    }    try    {      float f1 = bc.b(str1);      if (f1 < 4900.0F)        com.wuba.c.a.a(getContentResolver(), false);      if (f1 == 4700.0F)      {        SharedPreferences localSharedPreferences = getSharedPreferences("com.wuba_other_file", 0);        str2 = localSharedPreferences.getString("MD5PWD", "");        str3 = localSharedPreferences.getString("USERNAME", "");        str4 = localSharedPreferences.getString("USERID", "");        new StringBuilder("userName:").append(str3).append(",md5pwd:").append(str2);        localbw = bw.a(this);      }    }    catch (Exception localException1)    {      try      {        String str2;        String str3;        String str4;        bw localbw;        localbw.b = new f().b(new String(com.wuba.android.lib.util.commons.b.a("Mm1oc2ktMXNzM0A9c21AI3NqPTQ4KnNqdzAyamg=".toCharArray())), str2);        label180: localbw.c = str4;        localbw.a = str3;        localbw.d();        while (true)        {          this.i = new Thread(new com.wuba.j.c(this));          this.i.start();          bw.a(this).f();          return;          localException1 = localException1;          localException1.getMessage();        }      }      catch (Exception localException2)      {        break label180;      }    }  }  public final void a()  {    g = true;    Intent localIntent1 = getIntent();    Bundle localBundle = localIntent1.getExtras();    boolean bool;    String str7;    String str8;    String str9;    Intent localIntent6;    if (localBundle == null)    {      bool = false;      if (!bool)        break label245;      if (!bf.bb(this))        bf.bc(this);      String str6 = localBundle.getString("jump_protocol");      str7 = localBundle.getString("pre_key_third_folder_city_id");      str8 = localBundle.getString("pre_key_third_folder_city_dir");      str9 = localBundle.getString("pre_key_third_folder_city_name");      if (TextUtils.isEmpty(str6))        break label184;      localIntent6 = com.wuba.trade.api.b.c.b(this, str6);      if (localIntent6 != null)        break label148;      localIntent6 = new Intent();      localIntent6.setClass(this, HomeActivity.class);      label111: localIntent6.putExtra("third_folder_shortcut_intent", true);      startActivity(localIntent6);      finish();    }    label148: label184: label245: for (int n = 1; ; n = 0)    {      if (n == 0)        break label251;      return;      bool = at.b(localBundle);      break;      localIntent6.putExtra("pre_key_third_folder_city_id", str7);      localIntent6.putExtra("pre_key_third_folder_city_dir", str8);      localIntent6.putExtra("pre_key_third_folder_city_name", str9);      break label111;      String str10 = localBundle.getString("third_folder_class_name");      Intent localIntent5 = new Intent();      if (!TextUtils.isEmpty(str10))        localIntent5.setClassName(this, str10);      while (true)      {        startActivity(localIntent5);        finish();        break;        localIntent5.setClass(this, HomeActivity.class);      }    }    label251: String str1 = localIntent1.getStringExtra("random_num");    if ((localIntent1.getBooleanExtra("is_notify_distribute", false)) && (!bf.a(this, str1)))    {      startActivity((Intent)localIntent1.getParcelableExtra("intent"));      finish();      overridePendingTransition(a.a.slide_in_right, a.a.slide_out_right);      return;    }    if ((localBundle != null) && (at.c(localBundle)))    {      String str2 = localBundle.getString("shortcut_protocol");      if (!TextUtils.isEmpty(str2))      {        Intent localIntent4 = com.wuba.trade.api.b.c.b(this, str2);        localIntent4.addFlags(335544320);        startActivity(localIntent4);        finish();        overridePendingTransition(a.a.slide_in_right, a.a.slide_out_right);        return;      }      Intent localIntent3 = new Intent();      String str3 = localIntent1.getStringExtra("shortcut_intent_class");      String str4;      au localau;      if ("CategoryListActivity".equals(str3))      {        str3 = CategoryListActivity.class.getCanonicalName();        localIntent3.setClassName(this, str3);        str4 = localBundle.getString("shortcut_title");        if ((!localBundle.containsKey("intent_data_tag_string")) || (TextUtils.isEmpty(localBundle.getString("intent_data_tag_string"))))          break label630;        localau = at.a(localBundle);        if (localau != null)          break label551;        localIntent3.setClass(this, HomeActivity.class);      }      while (true)      {        finish();        overridePendingTransition(0, 0);        return;        if ("GroupBuyHomeActivity".equals(str3))        {          str3 = GroupBuyHomeActivity.class.getCanonicalName();          break;        }        if ("InfoListActivityGroup".equals(str3))        {          str3 = InfoListFragmentActivity.class.getCanonicalName();          break;        }        if (!"RecruitCateActivity".equals(str3))          break;        str3 = RecruitCateActivity.class.getCanonicalName();        break;        label551: localau.q = au.a.e;        if (!TextUtils.isEmpty(str4))          localau.e = str4;        String str5 = localBundle.getString("cate_id");        localIntent3.putExtra("list_name", localBundle.getString("list_name"));        localIntent3.putExtra("cate_id", str5);        localIntent3.putExtra("jump_bean", localau);        startActivity(localIntent3);      }      label630: if (WeatherDetailActivity.class.getCanonicalName().equals(str3))      {        localIntent3.setClass(this, WeatherDetailActivity.class);        localBundle.putBoolean("shortcut_intent", true);      }      while (true)      {        localIntent3.putExtras(localBundle);        startActivity(localIntent3);        break;        if (!RecruitCateActivity.class.getCanonicalName().equals(str3))        {          localIntent3.setClass(this, HomeActivity.class);          continue;        }        if (TextUtils.isEmpty(str4))          continue;        localBundle.putString("shortcut_title", str4);      }    }    Intent localIntent2 = new Intent();    if ((!j.b(getApplicationContext(), "has_used_app")) || (bf.L(this)))    {      j.b(getApplicationContext(), "has_used_app", true);      j.b(getApplicationContext(), "from_launch", true);      localIntent2.setClass(this, LeadingActivity.class);    }    while (true)    {      startActivity(localIntent2);      finish();      overridePendingTransition(0, 0);      return;      j.l(getApplicationContext(), "from_launch");      localIntent2.setClass(this, HomeActivity.class);    }  }  protected void onActivityResult(int paramInt1, int paramInt2, Intent paramIntent)  {    if (paramInt1 == 100)      d();  }  public void onBackPressed()  {  }  protected void onCreate(Bundle paramBundle)  {    String str1 = com.wuba.android.lib.util.commons.e.b + "/shared_prefs/com.wuba.xml";    String str2 = com.wuba.android.lib.util.commons.e.b + "/shared_prefs/com.wuba_new_v5.xml";    File localFile1 = new File(str1);    File localFile2 = new File(str2);    if ((localFile1.exists()) && (!localFile2.exists()));    while (true)    {      String str6;      String str7;      try      {        com.wuba.android.lib.util.c.b.a(localFile1, localFile2);        Iterator localIterator = com.wuba.databaseprovider.c.f(getContentResolver()).entrySet().iterator();        if (!localIterator.hasNext())          continue;        Map.Entry localEntry = (Map.Entry)localIterator.next();        str6 = (String)localEntry.getKey();        str7 = (String)localEntry.getValue();        if (!str6.equals("ISLOGIN"))          break label366;        if (!"true".equals(str7))          break label360;        bool2 = true;        j.b(this, str6, bool2);        new StringBuilder("Key=").append((String)localEntry.getKey()).append("---->value=").append((String)localEntry.getValue());        continue;      }      catch (IOException localIOException)      {        localIOException.getMessage();        bf.a(this, getSharedPreferences("wuba_main", 0).getString("versionName", ""));      }      super.onCreate(paramBundle);      if ((com.wuba.j.i.b(getApplicationContext()) != 1) && (!WubaHybridApplication.a))        break;      bm.a locala1 = new bm.a(this);      bm.a locala2 = locala1.a("提示");      locala2.a = "系统出了点小问题,请重新启动应用";      locala2.c = new e(this);      locala2.a("确定", new d(this));      bm localbm = locala1.a();      localbm.setCanceledOnTouchOutside(false);      localbm.show();      return;      label360: boolean bool2 = false;      continue;      label366: if (str6.equals("ISAUTOLOGIN"))      {        if (TextUtils.isEmpty(str7));        for (int n = 0; ; n = Integer.valueOf(str7).intValue())        {          j.b(this, str6, n);          break;        }      }      j.b(this, str6, str7);    }    NBSAppAgent.setLicenseKey("11b451575622485ea9a046de024fa83d").withCrashReportEnabled(false).withLocationServiceEnabled(true).start(this);    if ((getIntent() != null) && (getIntent().getBooleanExtra("launcht_activity_theme", false)))      setTheme(a.l.Theme_Launch_NORMAL);    while (true)    {      WubaHybridApplication localWubaHybridApplication = (WubaHybridApplication)getApplication();      String str3 = bf.a(localWubaHybridApplication);      label533: Intent localIntent3;      label633: String str4;      String str5;      if (com.wuba.android.lib.util.commons.e.c.equals(str3))      {        bf.e(localWubaHybridApplication, false);        new StringBuilder("WubaPersistentUtils.versionIsUpdate(this)=").append(bf.L(localWubaHybridApplication));        bf.a(localWubaHybridApplication, 0);        localWubaHybridApplication.a(false);        Context localContext = getApplicationContext();        String[] arrayOfString = new String[1];        arrayOfString[0] = bf.W(getApplicationContext());        com.wuba.utils.a.a(localContext, "main", "loading", arrayOfString);        new ActionLogObservService();        ActionLogObservService.a(this, 25);        localIntent3 = getIntent();        if (localIntent3.getBooleanExtra("shortcut_intent", false))        {          if (!localIntent3.getBooleanExtra("weather_shortcut_intent", false))            break label1122;          com.wuba.utils.a.a(this, "start", "desktopicon", new String[] { "weather" });        }        com.wuba.utils.a.a(this, "start", "connect", new String[0]);        if (!TextUtils.isEmpty(bf.q(this)))          bf.m(this, "");        bw.a(this);        ((WubaHybridApplication)getApplication()).d();        setContentView(a.i.launch);        getFilesDir().getAbsolutePath();        str4 = getFilesDir() + File.separator + "loadingImg";        if (!new File(str4 + File.separator + "loading_img.jpg").exists())          break label1153;        str5 = str4 + File.separator + "loading_img.jpg";        label793: this.k = str5;        if (!TextUtils.isEmpty(this.k))          break label1231;        bf.g(this, "0", "0");        this.e = false;        ((ViewStub)findViewById(a.g.launch_native_stub)).inflate();        label838: com.wuba.utils.q.e = true;      }      try      {        boolean bool1 = "mounted".equals(Environment.getExternalStorageState());        if (bool1);        while (true)        {          r.a(this);          if (!com.wuba.android.lib.util.d.i.e(this))            break label1288;          OpenClientIntentService.a(this, "launcher");          new c.a(com.wuba.activity.home.a.c.a(this), 0).start();          return;          setTheme(a.l.Theme_Launch);          break;          if (k.a(str3))          {            bf.a(localWubaHybridApplication, com.wuba.android.lib.util.commons.e.c);            bf.e(localWubaHybridApplication, true);            bf.a(localWubaHybridApplication, null, null, null);            bf.a(localWubaHybridApplication, 1);            bf.a(localWubaHybridApplication, false);            localWubaHybridApplication.a(true);            break label533;          }          if (!bc.a(str3, com.wuba.android.lib.util.commons.e.c))            break label533;          if (bc.a(str3)) { Intent localIntent1 = new Intent("com.android.launcher.action.UNINSTALL_SHORTCUT"); Intent localIntent2 = new Intent(); localIntent2.setAction("android.intent.action.MAIN"); localIntent2.addCategory("android.intent.category.LAUNCHER"); localIntent2.setComponent(new ComponentName(localWubaHybridApplication.getApplicationContext().getPackageName(), "com.wuba.activity.main.LaunchActivity")); localIntent1.putExtra("android.intent.extra.shortcut.INTENT", localIntent2); localWubaHybridApplication.sendBroadcast(localIntent1); bf.z(localWubaHybridApplication, ""); bf.a(localWubaHybridApplication, null, null, null); }           bf.b(localWubaHybridApplication, str3);          bf.m(localWubaHybridApplication, str3);          bf.Q(localWubaHybridApplication);          bf.a(localWubaHybridApplication, com.wuba.android.lib.util.commons.e.c);          bf.e(localWubaHybridApplication, true);          bf.a(localWubaHybridApplication, false);          bf.a(localWubaHybridApplication, 1);          localWubaHybridApplication.a(true);          break label533;          label1122: com.wuba.utils.a.a(this, "start", "desktopicon", new String[] { localIntent3.getExtras().getString("list_name") });          break label633;          label1153: if (new File(str4 + File.separator + "loading_img.png").exists())          {            str5 = str4 + File.separator + "loading_img.png";            break label793;          }          str5 = null;          break label793;          label1231: this.e = true;          m.a().a(this.m);          break label838;          if (com.wuba.android.lib.util.c.b.a(getFilesDir()) > 500L)            continue;          Toast.makeText(this, "没有闪存或SD卡,可能看不到图片", 1).show();        }      }      catch (Exception localException)      {        while (true)        {          localException.getMessage();          continue;          label1288: OpenClientIntentService.a(this);        }      }    }  }  public void onDestroy()  {    c();    View localView = findViewById(a.g.launch_native_layout);    if ((localView != null) && (localView.getParent() != null))    {      localView.setBackgroundColor(-1);      ImageView localImageView = (ImageView)localView.findViewById(a.g.launch_native_logo);      if (localImageView != null)        localImageView.setImageBitmap(null);      ((ViewGroup)localView.getParent()).removeView(localView);    }    super.onDestroy();  }  protected void onNewIntent(Intent paramIntent)  {    super.onNewIntent(paramIntent);    bf.a(this, paramIntent.getStringExtra("random_num"));  }  protected void onResume()  {    super.onResume();    d();  }}

可以看出红色粗体的那块代码就是卸载当前快捷方式的代码;那么快捷方式在那里创建的呢?那么那个半透明的界面是怎么出来的呢?

不急不急:

通过检索看到b.java文件:

package com.wuba.thirdapps;import android.content.Context;import android.content.Intent;import android.content.Intent.ShortcutIconResource;import android.content.res.Resources;import android.os.Build;import android.os.Build.VERSION;import com.wuba.android.lib.util.commons.e;import com.wuba.application.WubaHybridApplication;import com.wuba.f.a.f;import com.wuba.f.a.k;import com.wuba.g.az;import com.wuba.model.bo;import com.wuba.utils.at;import com.wuba.utils.ax;import com.wuba.utils.bf;import org.apache.http.client.methods.HttpGet;import org.apache.http.message.BasicNameValuePair;final class b  implements Runnable{  b(ThirdAppApplication paramThirdAppApplication, Context paramContext)  {  }  public final void run()  {    try    {      com.wuba.a locala = ((WubaHybridApplication)(WubaHybridApplication)this.a.getApplicationContext()).c;      BasicNameValuePair[] arrayOfBasicNameValuePair = new BasicNameValuePair[4];      arrayOfBasicNameValuePair[0] = new BasicNameValuePair("ua", ax.d(Build.MANUFACTURER + "#" + Build.MODEL));      arrayOfBasicNameValuePair[1] = new BasicNameValuePair("ver", ax.d(Build.VERSION.RELEASE));      arrayOfBasicNameValuePair[2] = new BasicNameValuePair("sdkver", ax.d(Build.VERSION.SDK));      arrayOfBasicNameValuePair[3] = new BasicNameValuePair("channelid", e.d);      HttpGet localHttpGet = locala.b.a("http://platform.58.com/api/speedy", arrayOfBasicNameValuePair);      bo localbo = (bo)locala.b.a(localHttpGet, new az());      if ((localbo != null) && (localbo.a))      {        Context localContext = this.a;        String str = localContext.getResources().getString(a.k.app_third_folder_name);        if (!at.a(localContext.getApplicationContext(), str))        {          com.wuba.utils.a.a(localContext.getApplicationContext(), "main", "tools", new String[0]);          Intent localIntent1 = new Intent("com.android.launcher.action.INSTALL_SHORTCUT"); localIntent1.putExtra("android.intent.extra.shortcut.NAME", str); localIntent1.putExtra("duplicate", false); Intent localIntent2 = new Intent(); localIntent2.setAction("android.intent.action.MAIN"); localIntent2.setClassName(localContext, "com.wuba.plugins.ThirdFolderActivity"); localIntent1.putExtra("android.intent.extra.shortcut.INTENT", localIntent2); localIntent1.putExtra("android.intent.extra.shortcut.ICON_RESOURCE", Intent.ShortcutIconResource.fromContext(localContext, a.f.wb_app_third_icon)); localContext.sendBroadcast(localIntent1); new Thread(new com.wuba.utils.d(localContext, str)).start();        }      }      bf.bc(this.a);      return;    }    catch (Exception localException)    {    }  }}

创建快捷方式,点击快捷方式跳转到ThirdFolderActivity.java界面
由此可知快捷方式是ThirdFolderActivity界面创建的,并且确定点击快捷方式显示的Activity就是ThirdFolderActivity,通过wb_app_third_icon查看drawable下面的资源文件也确定这是58快捷方式的对应的界面。

那么就可知道58骚当入口的实现其实是这样子的:

1,ThirdFolderActivity界面就是点击快捷方式显示的那个半透明的显示7个模块图标的界面,当然跳转肯定是intent的拉。

2,界面半透明效果,style文件如下:

<style name="DialogActivity" parent="@android:style/Theme.Dialog">        <item name="android:windowBackground">@*android:color/transparent</item>        <item name="android:windowFrame">@null</item>        <item name="android:windowNoTitle">true</item>        <item name="android:windowIsTranslucent">true</item>        <item name="android:windowAnimationStyle">@*android:style/Animation.Dialog</item>    </style>

3,删除主应用的快捷方式,添加这个界面的快捷方式。

于是一个骚当的快捷方式实现了。

更多相关文章

  1. Android:如何从堆栈中还原ProGuard混淆后的代码
  2. android recovery 主系统代码分析
  3. AndroidManifest.xml文件详解(manifest)
  4. Android学习笔记_53_Android界面的基本属性
  5. Android生成签名文件并用其对apk文件进行签名

随机推荐

  1. 代码里面修改layout_gravity
  2. java.lang.UnsatisfiedLinkError: No imp
  3. SwipeRefreshLayout使用小记
  4. android 发送e-mail实例
  5. Android(安卓)隐藏虚拟导航栏
  6. mac 电脑的android studio 启动的时候报
  7. Android设置屏幕方向
  8. AndroidX和android.support对照表
  9. Android(安卓)CTS Verifier Sensor Test
  10. Android动态控制Activity全屏