破晓 发表于 2015-1-19 11:32:28

彻底解决UC悬浮与AIR项目的兼容性

关于UC的ANE我已经改动很多次了。为了适应Starling的GPU渲染项目(-app.xml中的direct),从登录界面的横竖屏到支付界面的消失 再到悬浮的BUG 一路过来总是那么苛刻。前几天发版本,UC审核人员又把悬浮的问题拿出来说,忍无可忍,没办法只好再次对UC ANE进行修改。这次改动后,悬浮BUG会彻底解决。首先把在接UC SDK过程中遇到的问题先复述一遍:UC 与AIR项目兼容性BUG:
[*]支付界面竖屏 在横屏的starling项目的时候点击支付会闪退。解决方式是把全部UC界面换成横屏:传送门,
[*]上面这种方式被官方人员彻底否决 于是又有了一种解决方式:传送门
[*]点击悬浮打开随便一个SDK界面按下home之后游戏context会丢失,屏幕黑屏(再次按下home再次打开恢复)。解决方式:是 把在flash做悬浮 并固定,把悬浮的回调函数切换到调用个人账户中心 同样需要中转activity;
[*]阉割版本的flash悬浮图标UC官方无法接受 必须把悬浮恢复原样。这个问题正是本文要讨论的。并解决【3】所描述的BUG;
把悬浮中插入自定义activity的实现:关于UC悬浮与Starling项目的兼容性BUG重现:限定环境:AIR+Starling+横屏
[*]点击悬浮 随意点进去一个SDK界面 例如 【礼包】;
[*]按下【home】物理键;
[*]再打开AIR应用程序发现黑屏 游戏界面已消失;
[*]再次按下【home】;
[*]再次打开AIR应用程序 游戏界面恢复;

首先查看UCSDK需要配置的xml参数:<font color="rgb(51, 51, 51)">

                <activity android:configchanges="keyboardHidden|orientation|screenSize"
                android:label="@string/app_name" android:name="cn.uc.gamesdk.view.SdkWebActivity_s"
                android:theme="@android:style/Theme.Translucent"
                android:screenOrientation="landscape"
                android:windowSoftInputMode="adjustResize" >
               
               
               
               
               
</font>显然只有一个activity。也就是说UCSDK所有的界面都是基于这个Activiry;
然后分析 【游戏主activity-悬浮-悬浮打开的界面activity】 之间的关系。结构大概如下图:




按照官方ANE的做法激活悬浮,在代码中活动对象(context.getActiviry())的传输过程如图:





原理是悬浮通过获取游戏主activity的对象去打开上层SDK界面。正是由于传入的是游戏主activity对象给SDK界面 所以在按下home的时候 游戏主activity会在栈堆中被切掉。所以解决这个问题的关键在于在【悬浮-打开SDK界面】的过程中 传入一个新建的activity 而非AIR应用程序主activity。如下图:





这样便可解决开启了direct模式的AIR应用程序 与UC悬浮的兼容性BUG。以下是代码分析我们知道android java打开activity无非就是startActiviry几个类似的函数。悬浮按钮打开界面也是一样的。反编译出来UC SDK搜索startActiviry 大概可以定位到这里:
cn.uc.gamesdk.viewpackage cn.uc.gamesdk.view;

import android.content.Context;
import android.content.Intent;
import cn.uc.gamesdk.UCUIStyle;
import cn.uc.gamesdk.b.e;
import cn.uc.gamesdk.service.CommonService;
import org.json.JSONException;
import org.json.JSONObject;

public class g
{
private static final String p = "pageTitle";
private static final String q = "pageId";
public static final String a = "uiBusiness";
public static final String b = "login";
public static final String c = "pay";
public static final String d = "userCenter";
public static final String e = "h5EntryKey";
public static final String f = "login";
public static final String g = "pay";
public static final String h = "user_center";
public static final String i = "update_pwd";
public static final String j = "forget_pwd";
public static final String k = "login_game";
public static final String l = "register";
public static final String m = "alpha_code";
public static final String n = "game_not_open";
public static final String o = "nativePageId";

public static void a(String h5EntryKey, String uiBusiness, int pageId, String pageTitle)
{
    JSONObject jsonObj = new JSONObject();
    try {
      jsonObj.put("uiBusiness", uiBusiness);
      jsonObj.put("pageId", pageId);
      jsonObj.put("pageTitle", pageTitle);
    } catch (JSONException e) {
      e.printStackTrace();
    }
    CommonService.currentNativeSourcePageInfo = jsonObj;
    a(h5EntryKey, uiBusiness);
}

public static void a(int pageId, String uiBusiness)
{
    CommonService.currentNativeSourcePageInfo = null;
    b(pageId, uiBusiness);
}

public static boolean a()
{
    JSONObject jsonObj = CommonService.currentNativeSourcePageInfo;
    if (jsonObj != null) {
      int pageId = jsonObj.optInt("pageId");
      String uiBusiness = jsonObj.optString("uiBusiness");
      a(pageId, uiBusiness);
      return true;
    }
    return false;
}

public static void a(String uiBusiness)
{
    if ("login".equals(uiBusiness)) {//SDK登录
      if (e.s == UCUIStyle.SIMPLE)
      b(1, uiBusiness);
      else {
      a("login", uiBusiness);
      }
      return;
    }

    if ("pay".equals(uiBusiness)) {//SDK支付
      a("pay", uiBusiness);
      return;
    }

    if ("userCenter".equals(uiBusiness)) {//SDK个人中心
      a("user_center", uiBusiness);
      return;
    }

    a(uiBusiness, uiBusiness);//SDK其他界面礼包 账户 帮组 攻略等通过悬浮打开的界面
}

private static void a(String h5EntryKey, String uiBusiness)
{
    Intent intent = new Intent(e.b, SdkWebActivity.class);
    intent.putExtra("h5EntryKey", h5EntryKey);
    intent.putExtra("uiBusiness", uiBusiness);
    intent.putExtra("activity_work_type", 2);
    int flags = 805306368;
    intent.setFlags(flags);
    e.b.startActivity(intent);
}

private static void b(int nativePageId, String uiBusiness)
{
    Intent intent = new Intent(e.b, SdkWebActivity.class);
    intent.putExtra("uiBusiness", uiBusiness);
    intent.putExtra("nativePageId", nativePageId);
    intent.putExtra("activity_work_type", 4);
    int flags = 805306368;
    intent.setFlags(flags);
    e.b.startActivity(intent);
}

public static void b()
{
    Intent intent = new Intent(e.b, SdkWebActivity.class);
    intent.putExtra("uiBusiness", "pay");
    intent.putExtra("activity_work_type", 3);
    intent.setFlags(872415232);
    e.b.startActivity(intent);
}
}由此可以看出。悬浮打开的界面都通过此函数:private static void a(String h5EntryKey, String uiBusiness)
{
    Intent intent = new Intent(e.b, SdkWebActivity.class);
    intent.putExtra("h5EntryKey", h5EntryKey);
    intent.putExtra("uiBusiness", uiBusiness);
    intent.putExtra("activity_work_type", 2);
    int flags = 805306368;
    intent.setFlags(flags);
    e.b.startActivity(intent);
}所以只要在此函数中 新建Activiry 然后再传入intent 再启动界面 便可。然后在UC资源的json中可以发现【账户】【礼包】【攻略】【帮助】等五个界面的key分别为:账户 user_center
论坛 bbs
礼物 gift
攻略strategy
帮助 feedback
如此变可把此函数修改为如下:private static void a(String h5EntryKey, String uiBusiness)
    {
      Log.d("h5EntryKey", h5EntryKey);
      Log.d("uiBusiness", uiBusiness);

      Log.d("Xmsh_isFloat", newAcitvity.isFloat.toString());
//启动新的activity传入Intent newAcitvity 需在-app.xml中定义
//newAcitvity.isFloat 判断当启动的界面是悬浮打开的子界面时再使用 其他一律按照原来的流程
      if(newAcitvity.isFloat)
      {
            Log.d("newAcitvity", "-new---activity---begin--");
            newAcitvity.selectKey = 0;
            Intent intent = new Intent(newAcitvity.MYACTIVITY_ACTION);
            intent.putExtra("selectKey", 0);
            intent.putExtra("h5EntryKey", h5EntryKey);
            intent.putExtra("uiBusiness", uiBusiness);
            if(UCFShowFloatButton_sus.static_context != null)
            {
                Log.d("newAcitvity", "---static_context--");
                UCFShowFloatButton_sus.static_context.getActivity().startActivityForResult(intent, 0);
                return;
            }

            Log.d("newAcitvity", "------static_context is null--");
      }

      Intent intent_beitai = new Intent(cn.uc.gamesdk.b.e.b, SdkWebActivity_s.class);
      intent_beitai.putExtra("h5EntryKey", h5EntryKey);
      intent_beitai.putExtra("uiBusiness", uiBusiness);
      intent_beitai.putExtra("activity_work_type", 2);
      int flags = 805306368;
      intent_beitai.setFlags(flags);
      cn.uc.gamesdk.b.e.b.startActivity(intent_beitai);
    }如此遍解决了这个问题
流程是:
1.复制UC源码库的cn.uc.gamesdk.view.g.java 写入ANE;
2.删除UC 源码库的cn.uc.gamesdk.view.g.java;
3.修改g.java 然后合并jar;
本文来自:http://shadowkong.com/archives/1307



nofastfat 发表于 2015-5-21 10:24:43

兄弟,能把ane共享一个吗,最好是IOS和android都有,UC官方的ANE太老了,完全没法用
邮箱:xiey147@163.com
好人一生平安

破晓 发表于 2015-5-21 10:44:12

nofastfat 发表于 2015-5-21 10:24
兄弟,能把ane共享一个吗,最好是IOS和android都有,UC官方的ANE太老了,完全没法用
邮箱:xiey147@163.com
...

找rect

http://shadowkong.com/archives/1307
页: [1]
查看完整版本: 彻底解决UC悬浮与AIR项目的兼容性