1. 程式人生 > >android 埋點統計方案---已廢棄

android 埋點統計方案---已廢棄

  • 最近在研究埋點統計,經過認真調研,整理出了我們自己的一套埋點方案,採用統計所有view點選事件的方案。由於網上內容有很多錯誤或不完整,本文將所有相關技術分析和程式碼完整的貼出來方便大家直接用,可以繞開好多彎路。

    本文解決一大問題是在有Fragment切換的時候,Fragment中的view與上一個Fragment中的view出現了衝突的問題,即在viewPage中會預先載入好下一個Fragment,造成點選事件統計衝突。view.isShown()用於判斷fragment是否為當前展示的那一個。

BaseActivity中程式碼

//統計埋點
    LinkedHashSet<View> views = new
LinkedHashSet<View>(); public LinkedHashSet<View> allView = new LinkedHashSet<View>(); int statusBarHeight; private String mClassName = this.getClass().getSimpleName(); //分發點選事件 @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { View view = getCurrentFocus(); if
(isHideInput(view, ev)) { HideSoftInput(view.getWindowToken()); } }else if(ev.getAction() == MotionEvent.ACTION_UP){ /*獲取當前點選位置,遍歷佈局,獲取當前點選位置對應的view,根據view對映路徑,與json檔案中的對比*/ eventInViewCollect( ev); } return super.dispatchTouchEvent(ev); } @Override
public void onWindowFocusChanged (boolean hasFocus){ super.onWindowFocusChanged(hasFocus); if(!hasFocus) return; //失去焦點時 不執行 collectView();//收集統計用點選view的資訊 } public void eventInViewCollect(MotionEvent event) { if (!HengChangAgent.isCollectMode()) return; //非收集模式 退出 double x = event.getRawX(); double y = event.getRawY() - statusBarHeight; List touchViewid = new ArrayList<String> (); for(View view :allView) { Rect outRect = new Rect(); view.getGlobalVisibleRect(outRect); if(outRect.contains((int)x ,(int)y )){ String idName = ViewUtils.getResourceName(this,view.getId()); // view.isShown() view在上層才獲取其id 針對多個fragment切換情況 if(!TextUtils.isEmpty(idName) && view.isShown()){ touchViewid.add(idName); } if (touchViewid.size()>0){ LogUtils.d("HengChangAgent" , "這是我們的埋點:"+touchViewid.toString()); String json= ""; try { JSONObject jsonObj = new JSONObject();//物件,json形式 jsonObj.put("idName", touchViewid.toString());//向物件裡面新增值 json = jsonObj.toString(); } catch (Exception e) { LogUtils.d("out" , "埋點json生成失敗"); } HengChangAgent.requestBuriedPointStatistics(/*AppAccount.getInstance().getUserid()+*/"",json); } } } } /** * 收集統計用點選view的資訊 */ public void collectView() { if (!HengChangAgent.isCollectMode()) return; //非收集模式 退出 ViewGroup rootView = ViewUtils.getRootFrame(this); allView = getView(rootView); //獲取到 //過濾掉沒有定義過id的view LinkedHashSet<View> tempView = new LinkedHashSet<View>(); for (View view :allView){ String idName = ViewUtils.getResourceName(this,view.getId()); if(!TextUtils.isEmpty(idName)){ tempView.add(view); } } allView = tempView; LogUtils.d("out" , allView.size()+""); Rect outRect = new Rect(); this.getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect); statusBarHeight = outRect.top; } /*獲取所有View和沒有子View的ViewGroup*/ public LinkedHashSet<View> getView(ViewGroup viewGroup){ if(viewGroup == null) return null; int count = viewGroup.getChildCount(); for(int i=0;i<count;i++){ View view = viewGroup.getChildAt(i); if(!(view instanceof ViewGroup)){ views.add(viewGroup); views.add(view); }else if(view instanceof ViewGroup){ getView((ViewGroup)view); }else{ break; } } return views; }

BaseFragment中的onActivityCreated()新增如下程式碼

  /**
     * 收集統計用點選view的資訊
     */
    public void collectView() {
        if (!HengChangAgent.isCollectMode())   return;//非收集模式  退出

        if (getActivity() instanceof BaseActivity ){
            ViewGroup rootView =  ViewUtils.getRootFrame(getActivity());//獲取根viewGroup
            LinkedHashSet<View> views = ((BaseActivity)getActivity()).getView(rootView);
            if (views ==null || views.size()==0 ) return;

            //過濾掉沒有定義過id的view
            LinkedHashSet<View> filterViews = new LinkedHashSet<View>();
            for (View view :views){
                String idName = ViewUtils.getResourceName(getActivity(),view.getId());
                if(!TextUtils.isEmpty(idName) && idName.contains(":id/")){
                    filterViews.add(view);
                }
            }
            ((BaseActivity)getActivity()).allView.addAll(filterViews);
        }
    }

相關工具類

public class ViewUtils {

    //獲取Activity的根view
    @NonNull
    public static FrameLayout getRootFrame(@NonNull Activity activity) {
        View re = activity.findViewById(android.R.id.content);
        if (re != null && re instanceof FrameLayout) {
            return (FrameLayout) re;
        }
        ViewGroup viewGroup = (ViewGroup) activity.getWindow().getDecorView();
        re = viewGroup.getChildAt(viewGroup.getChildCount() - 1);
        if (re != null && re instanceof FrameLayout) {
            return (FrameLayout) re;
        } else {
            re = new FrameLayout(activity);
            activity.getActionBar().getHeight();
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT
                    , ViewGroup.LayoutParams.MATCH_PARENT);
            viewGroup.addView(re, lp);
            return (FrameLayout) re;
        }
    }

    /**
     * 獲取資原始檔名字
     * @param resid
     * @return
     */
    public static String getResourceName(@NonNull Context context , @AnyRes int resid){
        String res = "";
        if (-1 ==resid ) return res;
        try {
            res = context.getResources().getResourceName(resid);
        } catch (Resources.NotFoundException e) {
//            e.printStackTrace();
//            LogUtils.d("out", "未獲取到ResourceName ---id="+resid);
        }
        return res;
    }
    //獲取Activity的根view
    public static ViewGroup getRootView(Activity context)
    {
        return (ViewGroup)((ViewGroup)context.findViewById(android.R.id.content)).getChildAt(0);
    }
}