Notification弹出实现
Notification的几种基本使用方法,大家肯定都已经烂熟于心,我也不必多说.给一个链接:https://zhuanlan.zhihu.com/p/25841482
接下来我想说的是android5.0 后的弹出通知,
网上的方法是:
//第一步:实例化通知栏构造器Notification.Builder:
Notification.Builder builder =new Notification.Builder(MainActivity.this);//实例化通知栏构造器Notification.Builder,参数必填(Context类型),为创建实例的上下文
//第二步:获取状态通知栏管理:
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);//获取状态栏通知的管理类(负责发通知、清除通知等操作)
//第三步:设置通知栏PendingIntent(点击动作事件等都包含在这里):
Intent push =new Intent(MainActivity.this,MainActivity.class);//新建一个显式意图,第一个参数 Context 的解释是用于获得 package name,以便找到第二个参数 Class 的位置
//PendingIntent可以看做是对Intent的包装,通过名称可以看出PendingIntent用于处理即将发生的意图,而Intent用来用来处理马上发生的意图
//本程序用来响应点击通知的打开应用,第二个参数非常重要,点击notification 进入到activity, 使用到pendingIntent类方法,PengdingIntent.getActivity()的第二个参数,即请求参数,实际上是通过该参数来区别不同的Intent的,如果id相同,就会覆盖掉之前的Intent了
PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.this,0,push,0);
//第四步:对Builder进行配置:
builder
.setContentTitle("My notification")//标题
.setContentText("Hello World!")// 详细内容
.setContentIntent(contentIntent)//设置点击意图
.setTicker("New message")//第一次推送,角标旁边显示的内容
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher))//设置大图标
.setDefaults(Notification.DEFAULT_ALL);//打开呼吸灯,声音,震动,触发系统默认行为
/*Notification.DEFAULT_VIBRATE //添加默认震动提醒 需要VIBRATE permission
Notification.DEFAULT_SOUND //添加默认声音提醒
Notification.DEFAULT_LIGHTS//添加默认三色灯提醒
Notification.DEFAULT_ALL//添加默认以上3种全部提醒*/
//.setLights(Color.YELLOW, 300, 0)//单独设置呼吸灯,一般三种颜色:红,绿,蓝,经测试,小米支持黄色
//.setSound(url)//单独设置声音
//.setVibrate(new long[] { 100, 250, 100, 250, 100, 250 })//单独设置震动
//比较手机sdk版本与Android 5.0 Lollipop的sdk
if(android.os.Build.VERSION.SDK_INT>= android.os.Build.VERSION_CODES.LOLLIPOP) {
builder
/*android5.0加入了一种新的模式Notification的显示等级,共有三种:
VISIBILITY_PUBLIC只有在没有锁屏时会显示通知
VISIBILITY_PRIVATE任何情况都会显示通知
VISIBILITY_SECRET在安全锁和没有锁屏的情况下显示通知*/
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_DEFAULT)//设置该通知优先级
.setCategory(Notification.CATEGORY_MESSAGE)//设置通知类别
//.setColor(context.getResources().getColor(R.color.small_icon_bg_color))//设置smallIcon的背景色
.setFullScreenIntent(contentIntent, true)//将Notification变为悬挂式Notification
.setSmallIcon(R.drawable.ic_launcher);//设置小图标
}
else{
builder
.setSmallIcon(R.drawable.ic_launcher);//设置小图标
}
//第五步:发送通知请求:
Notification notify = builder.build();//得到一个Notification对象
mNotifyMgr.notify(1,notify);//发送通知请求
}
但上面的做法并不能在android5.0以下的设备上使通知弹出,因此下面的做法是自己重写Notification(网上查找的一些资料,来源忘记了,不好意思)
如果需要使通知自动显示,那么就需要我们在接收到通知后重新定义通知的界面,并使其加载显示在Window界面上,这点需要读者了解Window的加载机制.
其实简单点来说,就是通过windowManager的仅有的三个方法(加载,更新,删除)来实现的.如果有大神熟悉这方面的知识可以分享分享.
自定义Notification的思路:
1.继承重写NotificationCompat,Builder来实现类似的Notification
2.自定义通知界面
3.自定义NotificationManager,发送显示通知
废话不多说,先上主要代码:
 public class HeadsUp   {
     private Context context;
     /**
      * 出现时间  单位是 second
      */
     private long duration= 3;
     /**
      *
      */
     private Notification notification;
     private Builder builder;
     private boolean isSticky=false;
     private boolean activateStatusBar=true;
     private Notification silencerNotification;
     /**
      * 间隔时间
      */
     private int code;
     private CharSequence titleStr;
     private CharSequence msgStr;
     private int icon;
     private View customView;
     private boolean isExpand;
     private HeadsUp(Context context) {
         this.context=context;
     }
     public static class Builder  extends  NotificationCompat.Builder {
         private HeadsUp headsUp;
         public Builder(Context context) {
             super(context);
             headsUp=new HeadsUp(context);
         }
         public Builder setContentTitle(CharSequence title) {
             headsUp.setTitle(title);
             super.setContentTitle(title);        //状态栏显示内容
             return this;
         }
         public Builder setContentText(CharSequence text) {
             headsUp.setMessage(text);
             super.setContentText(text);
             return this;
         }
         public Builder setSmallIcon(int icon) {
             headsUp.setIcon(icon);
             super.setSmallIcon(icon);
             return this;
         }
         public HeadsUp buildHeadUp(){
             headsUp.setNotification(this.build());
             headsUp.setBuilder(this);
             return  headsUp;
         }
         public Builder setSticky(boolean isSticky){
             headsUp.setSticky(isSticky);
             return this;
         }
     }
     public Context getContext() {
         return context;
     }
     public long getDuration() {
         return duration;
     }
     public Notification getNotification() {
         return notification;
     }
     protected void setNotification(Notification notification) {
         this.notification = notification;
     }
     public View getCustomView() {
         return customView;
     }
     public void setCustomView(View customView) {
         this.customView = customView;
     }
     public int getCode() {
         return code;
     }
     protected void setCode(int code) {
         this.code = code;
     }
     protected Builder getBuilder() {
         return builder;
     }
     private void setBuilder(Builder builder) {
         this.builder = builder;
     }
     public boolean isSticky() {
         return isSticky;
     }
     public void setSticky(boolean isSticky) {
         this.isSticky = isSticky;
     }
 }
 public class HeadsUpManager  {
     private  WindowManager wmOne;
     private FloatView floatView;
     private Queue<HeadsUp> msgQueue;
     private static HeadsUpManager manager;
     private Context context;
     private boolean isPolling = false;
     private Map<Integer, HeadsUp> map;
     private   NotificationManager notificationManager=null;
     public static HeadsUpManager getInstant(Context c) {
         if (manager == null) {
             manager = new HeadsUpManager(c);
         }
         return manager;
     }
     private HeadsUpManager(Context context) {
         this.context = context;
         map = new HashMap<Integer, HeadsUp>();
         msgQueue = new LinkedList<HeadsUp>();
         wmOne = (WindowManager) context
                 .getSystemService(Context.WINDOW_SERVICE);
         notificationManager= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
     }
     public  void notify(HeadsUp headsUp) {
         if (map.containsKey(headsUp.getCode())) {
             msgQueue.remove(map.get(headsUp.getCode()));
         }
         map.put(headsUp.getCode(), headsUp);
         msgQueue.add(headsUp);
         if (!isPolling) {
             poll();
         }
     }
     public synchronized void notify(int code,HeadsUp headsUp) {
         headsUp.setCode(code);
         notify(headsUp);
     }
     public synchronized void cancel(HeadsUp headsUp) {
         cancel(headsUp.getCode());
     }
     private synchronized void poll() {
         if (!msgQueue.isEmpty()) {
             HeadsUp headsUp = msgQueue.poll();
             map.remove(headsUp.getCode());
 //            if ( Build.VERSION.SDK_INT < 21 ||   headsUp.getCustomView() != null ){
                 isPolling = true;
                 show(headsUp);
                 System.out.println("自定义notification");
 //            }else {
 //                //当 系统是 lollipop 以上,并且没有自定义布局以后,调用系统自己的 notification
 //                isPolling = false;
 //                notificationManager.notify(headsUp.getCode(),headsUp.getBuilder().setSmallIcon(headsUp.getIcon()).build());
 //                System.out.println("调用系统notification");
 //            }
         } else {
             isPolling = false;
         }
     }
     private void show(HeadsUp headsUp) {
         floatView = new FloatView(context, 20);
         WindowManager.LayoutParams params = FloatView.winParams;
         params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                 |WindowManager.LayoutParams.FLAG_FULLSCREEN
                 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
         params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
         params.width = WindowManager.LayoutParams.MATCH_PARENT;
         params.height = WindowManager.LayoutParams.WRAP_CONTENT;
         params.format = -3;
         params.gravity = Gravity.CENTER | Gravity.TOP;
         params.x = floatView.originalLeft;
         params.y = 10;
         params.alpha = 1f;
         wmOne.addView(floatView, params);
         ObjectAnimator a = ObjectAnimator.ofFloat(floatView.rootView, "translationY", -700, 0);
         a.setDuration(600);
         a.start();
         floatView.setNotification(headsUp);
         if(headsUp.getNotification()!=null){
             notificationManager.notify(headsUp.getCode(), headsUp.getNotification());
         }
     }
     public void cancel(){
         if(floatView !=null && floatView.getParent()!=null) {
             floatView.cancel();
         }
     }
     protected void dismiss() {
         if (floatView.getParent()!=null) {
             wmOne.removeView(floatView);
             floatView.postDelayed(new Runnable() {
                 @Override
                 public void run() {
                     poll();
                 }
             }, 200);
         }
     }
     protected   void  animDismiss(){
         if(floatView !=null && floatView.getParent()!=null){
             ObjectAnimator a = ObjectAnimator.ofFloat(floatView.rootView, "translationY", 0, -700);
             a.setDuration(700);
             a.start();
             a.addListener(new Animator.AnimatorListener() {
                 @Override
                 public void onAnimationStart(Animator animator) {
                 }
                 @Override
                 public void onAnimationEnd(Animator animator) {
                     dismiss();
                 }
                 @Override
                 public void onAnimationCancel(Animator animator) {
                 }
                 @Override
                 public void onAnimationRepeat(Animator animator) {
                 }
             });
         }
     }
     protected  void  animDismiss(HeadsUp headsUp){
            if(floatView.getHeadsUp().getCode()==headsUp.getCode()){
                animDismiss();
            }
     }
     public void cancel(int code) {
         if (map.containsKey(code)) {
             msgQueue.remove(map.get(code));
         }
         if(floatView!=null && floatView.getHeadsUp().getCode()==code){
             animDismiss();
         }
     }
     public void close() {
         cancelAll();
         manager = null;
     }
     public void cancelAll() {
         msgQueue.clear();
         if (floatView!=null && floatView.getParent()!=null) {
             animDismiss();
         }
     }
 }
 public class FloatView extends LinearLayout {
     private float rawX = 0;
     private float rawY=0;
     private float touchX = 0;
     private float startY = 0;
     public LinearLayout rootView;
     public int originalLeft;
     public int viewWidth;
     private float validWidth;
     private VelocityTracker velocityTracker;
     private  int maxVelocity;
     private Distance distance;
     private ScrollOrientationEnum scrollOrientationEnum=ScrollOrientationEnum.NONE;
     public static WindowManager.LayoutParams winParams = new WindowManager.LayoutParams();
     public FloatView(final Context context, int i) {
         super(context);
         LinearLayout view = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.notification_bg, null);
         maxVelocity= ViewConfiguration.get(context).getScaledMaximumFlingVelocity();
         rootView = (LinearLayout) view.findViewById(R.id.rootView);
         addView(view);
         viewWidth = context.getResources().getDisplayMetrics().widthPixels;
         validWidth=viewWidth/2.0f;
         originalLeft = 0;
     }
     public void setCustomView(View view) {
         rootView.addView(view);
     }
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
     }
     private HeadsUp headsUp;
     private long cutDown;
     private   Handler mHandle=null;
     private CutDownTime cutDownTime;
     private class CutDownTime extends Thread{
         @Override
         public void run() {
             super.run();
             while (cutDown>0){
                 try {
                     Thread.sleep(1000);
                     cutDown--;
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
             if(cutDown==0) {
                 mHandle.sendEmptyMessage(0);
             }
         }
     };
     public HeadsUp getHeadsUp() {
         return headsUp;
     }
 private int pointerId;
     public boolean onTouchEvent(MotionEvent event) {
         rawX = event.getRawX();
         rawY=event.getRawY();
         acquireVelocityTracker(event);
         cutDown= headsUp.getDuration();
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN:
                 touchX = event.getX();
                 startY = event.getRawY();
                 pointerId=event.getPointerId(0);
                 break;
             case MotionEvent.ACTION_MOVE:
                 switch (scrollOrientationEnum){
                     case NONE:
                         if(Math.abs((rawX - touchX))>20) {
                             scrollOrientationEnum=ScrollOrientationEnum.HORIZONTAL;
                         }else if(startY-rawY>20){
                             scrollOrientationEnum=ScrollOrientationEnum.VERTICAL;
                         }
                         break;
                     case HORIZONTAL:
                         updatePosition((int) (rawX - touchX));
                         break;
                     case VERTICAL:
                         if(startY-rawY>20) {
                            cancel();
                         }
                         break;
                 }
                 break;
             case MotionEvent.ACTION_UP:
                 velocityTracker.computeCurrentVelocity(1000,maxVelocity);
                 int dis= (int) velocityTracker.getYVelocity(pointerId);
                 if(scrollOrientationEnum==ScrollOrientationEnum.NONE){
                     if(headsUp.getNotification().contentIntent!=null){
                         try {
                             headsUp.getNotification().contentIntent.send();
                             cancel();
                         } catch (PendingIntent.CanceledException e) {
                             e.printStackTrace();
                         }
                     }
                     break;
                 }
                 int toX;
                 if(preLeft>0){
                     toX= (int) (preLeft+Math.abs(dis));
                 }else{
                     toX= (int) (preLeft-Math.abs(dis));
                 }
                 if (toX <= -validWidth) {
                     float preAlpha=1-Math.abs(preLeft)/validWidth;
                     preAlpha=preAlpha>=0?preAlpha:0;
                     translationX(preLeft,-(validWidth+10),preAlpha,0);
                 } else if (toX <= validWidth) {
                     float preAlpha=1-Math.abs(preLeft)/validWidth;
                     preAlpha=preAlpha>=0?preAlpha:0;
                     translationX(preLeft,0,preAlpha,1);
                 }else{
                     float preAlpha=1-Math.abs(preLeft)/validWidth;
                     preAlpha=preAlpha>=0?preAlpha:0;
                     translationX(preLeft, validWidth + 10, preAlpha, 0);
                 }
                 preLeft = 0;
                 scrollOrientationEnum=ScrollOrientationEnum.NONE;
                 break;
         }
         return super.onTouchEvent(event);
     }
     /**
      *
      * @param event 向VelocityTracker添加MotionEvent
      *
      * @see android.view.VelocityTracker#obtain()
      * @see android.view.VelocityTracker#addMovement(MotionEvent)
      */
     private void acquireVelocityTracker( MotionEvent event) {
         if(null == velocityTracker) {
             velocityTracker = VelocityTracker.obtain();
         }
         velocityTracker.addMovement(event);
     }
     private int preLeft;
     public void updatePosition(int left) {
             float preAlpha=1-Math.abs(preLeft)/validWidth;
             float leftAlpha=1-Math.abs(left)/validWidth;
             preAlpha = preAlpha>=0 ? preAlpha : 0;
             leftAlpha = leftAlpha>=0 ? leftAlpha : 0;
             translationX(preLeft,left,preAlpha,leftAlpha);
         preLeft = left;
     }
     public void translationX(float fromX,float toX,float formAlpha, final float toAlpha  ){
         ObjectAnimator a1=ObjectAnimator.ofFloat(rootView,"alpha",formAlpha,toAlpha);
         ObjectAnimator a2 = ObjectAnimator.ofFloat(rootView, "translationX", fromX, toX);
         AnimatorSet animatorSet=new AnimatorSet();
         animatorSet.playTogether(a1,a2);
         animatorSet.addListener(new Animator.AnimatorListener() {
             @Override
             public void onAnimationStart(Animator animation) {
             }
             @Override
             public void onAnimationEnd(Animator animation) {
                 if(toAlpha==0){
                     HeadsUpManager.getInstant(getContext()).dismiss();
                     cutDown=-1;
                     if(velocityTracker!=null) {
                         velocityTracker.clear();
                         try {
                             velocityTracker.recycle();
                         } catch (IllegalStateException e) {
                         }
                     }
                 }
             }
             @Override
             public void onAnimationCancel(Animator animation) {
             }
             @Override
             public void onAnimationRepeat(Animator animation) {
             }
         });
         animatorSet.start();
     }
     public void setNotification(final HeadsUp headsUp) {
         this.headsUp = headsUp;
         mHandle= new Handler(){
             @Override
             public void handleMessage(Message msg) {
                 super.handleMessage(msg);
                 HeadsUpManager.getInstant(getContext()).animDismiss(headsUp);
             }
         };
         cutDownTime=  new CutDownTime();
         if(!headsUp.isSticky()){
             cutDownTime.start();
         }
         cutDown= headsUp.getDuration();
         if (headsUp.getCustomView() == null) {
             View defaultView = LayoutInflater.from(getContext()).inflate(R.layout.notification, rootView, false);
             rootView.addView(defaultView);
             ImageView imageView = (ImageView) defaultView.findViewById(R.id.iconIM);
             TextView titleTV = (TextView) defaultView.findViewById(R.id.titleTV);
             TextView timeTV = (TextView) defaultView.findViewById(R.id.timeTV);
             TextView messageTV = (TextView) defaultView.findViewById(R.id.messageTV);
             imageView.setImageResource(headsUp.getIcon());
             titleTV.setText(headsUp.getTitleStr());
             messageTV.setText(headsUp.getMsgStr());
             SimpleDateFormat simpleDateFormat=new SimpleDateFormat("HH:mm");
             timeTV.setText( simpleDateFormat.format(new Date()));
         } else {
             setCustomView(headsUp.getCustomView());
         }
     }
     protected void cancel(){
         HeadsUpManager.getInstant(getContext()).animDismiss();
         cutDown = -1;
         cutDownTime.interrupt();
         if(velocityTracker!=null) {
             try {
                 velocityTracker.clear();
                 velocityTracker.recycle();
             } catch (IllegalStateException e) {
             }
         }
     }
     enum ScrollOrientationEnum {
         VERTICAL,HORIZONTAL,NONE
     }
 }
具体用法:
          PendingIntent pendingIntent=PendingIntent.getActivity(MainActivity.this,11,new Intent(MainActivity.this,MainActivity.class),PendingIntent.FLAG_UPDATE_CURRENT);
                View view=getLayoutInflater().inflate(R.layout.custom_notification, null);
                view.findViewById(R.id.openSource).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                    }
                });
                HeadsUpManager manage = HeadsUpManager.getInstant(getApplication());
                HeadsUp.Builder builder = new HeadsUp.Builder(MainActivity.this);
                builder.setContentTitle("提醒")
                       //要显示通知栏通知,这个一定要设置
                        .setSmallIcon(R.drawable.icon)
                        .setContentText("你有新的消息")
                        //2.3 一定要设置这个参数,负责会报错
                        .setContentIntent(pendingIntent)
                        //.setFullScreenIntent(pendingIntent, false)
                HeadsUp headsUp = builder.buildHeadUp();
                headsUp.setCustomView(view);
                manage.notify(1, headsUp);
            }
目前先这样吧,以后继续更新。。。
Notification弹出实现的更多相关文章
- Notification 弹出一个通知在桌面右下角
		if (!("Notification" in window)) { //alert("This browser does not support desktop not ... 
- 【wpf】在win10系统上弹出toast和notification
		原文:[wpf]在win10系统上弹出toast和notification 老规矩,先看效果 右下角的notification: 操作中心的notification: 整体效果: 前提条件 1.需要在 ... 
- iOS 自定义键盘ToolBar(与键盘的弹出、收起保持一致)
		1.监听键盘改变的通知 [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyBoardWillCha ... 
- iOS8无法弹出本地通知?
		最近在看<iOS编程(第4版)>(就是Big Nerd Ranch用的那本教材).这本书写的不错,推荐一下,写的很细致,循序渐进,不能不赞一下外国人写书的思路,确实跟国人不同.之前学And ... 
- 用Masonry实现键盘的收回和弹出
		首先说几点:我一般将数值类型的约束用mas_equalTo,而相对于某个控件,或者某个控件的某个约束,我会使用equalTo,如:make.size.mas_equalTo(CGSizeMake(10 ... 
- IOS开发之自定义系统弹出键盘上方的view(转载)
		这篇文章解决的一个开发中的实际问题就是:当弹出键盘时,自定义键盘上方的view.目前就我的经验来看,有两种解决方法.一个就是利用UITextField或者UITextView的inputAccesso ... 
- Android EditText 不弹出输入法
		当第一次进入一个activity的时候 一般是第一个edittext是默认选中的,但是该死的软键盘也一起弹出来了 那是相当的不美观哈!(#‵′)凸.为此, 本大人就去寻找在刚进入这个activity ... 
- [Prism框架实用分享]如何在主程序中合理的弹出子窗体
		大家好 说起子窗体,大家都会想到ChildWindow,多熟悉的一个控件.不错,Sliverlight中已经提供了子窗体的具体实现,而在WPF中却没有这么好的事情(有的第三方控件商已经提供此控件).最 ... 
- VS2010/MFC:模态对话框及其弹出过程
		模态对话框及其弹出过程 加法计算器对话框程序大家照着做一遍后,相信对基于对话框的程序有些了解了,有个好的开始对于以后的学习大有裨益.趁热打铁,这一节讲讲什么是模态对话框和非模态对话框,以及模态对话框怎 ... 
随机推荐
- Java基础语法<九>  接口与内部类
			1 接口 interface implement 接口的所有方法自动地属于public.因此,在接口中声明方法时,不必提供关键字public. 接口可以包含多个方法,接口中可以定义常量.接口中的 ... 
- MAC本上appium连接真机
			简单介绍一下appium连接ios真机测试环境的软件安装及配置过程: 目前我用的是desktop版本的appium, 所以MAC版本必须要升级到10.12以上,Xcode版本必须要在8.0以上,否则亲 ... 
- Android - DrawerLayout
			Android DrawerLayout 的使用 Android L Android Studio 1.4 从主视图左侧能抽出一个导航栏,效果图: 点击后弹出新界面: 新界面也可以抽出左侧导航栏 ... 
- 控制反转(IoC)-解析与实现
			控制反转(Inversion of Control)缩写:IoC是面向对象编程中框架级别里的一个重要的概念, 可以说Spring框架的核心就是基于IoC原理的. 这个概念到底是什么呢? 这么讲吧,一个 ... 
- 【原创】Easyui tree filter 过滤本地数据无效的原因
			Easyui tree filter 过滤本地数据无效的解决方式 正确使用方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ... 
- JavaScript中的call()、apply()与bind():
			关于call()与apply(): 在JavaScript中,每个函数都有call与apply(),这两个函数都是用来改变函数体内this的指向,并调用相关的参数. 看一个例子: 定义一个animal ... 
- ASP.NET Core MVC – Form Tag Helpers
			ASP.NET Core Tag Helpers系列目录 ASP.NET Core MVC Tag Helpers 介绍 ASP.NET Core MVC – Caching Tag Helpers ... 
- 基于ZYNQ的SOC——Hellow_World实验
			ZYNQ是一款SOC芯片,之前使用VGA做过的实验只是PL(Programmable Logic)部分,而ZYNQ最突出的功能,就是内部的双核Cortex-A9,所以从现在开始我将学习ZYNQ的SOC ... 
- suffix tree
			文章出处:http://www.cnblogs.com/snowberg/archive/2011/10/21/2468588.html 3 What is a Suffix Tree Suf ... 
- 案例:Standby RAC遭遇ORA-1157,1111,1110导致实例crash处理
			案例:Standby RAC遭遇ORA-1157,1111,1110导致实例crash处理 环境:RHEL 6.5 + Oracle RAC 11.2.0.4 + Dataguard 今天在实验环境的 ... 
