我创建了一个应用程序,它具有Facebook,聊天头等服务.在聊天头上点击,我正在启动一个Activity(参见MyActivity的代码).如下所述,我在特定情况下推迟启动活动
>点击聊天头;活动推出很好
>按主页按钮;根据我的逻辑,活动会破坏
>现在,如果我再次点击聊天头,它将启动延迟活动(少数
秒)
如果我清除最近活动堆栈中的活动,或者如果我按下后退按钮,则不会出现此问题.即使我删除了dispatchKeyEvent函数,问题仍然存在
public class MyActivity extends AppCompatActivity implements ChatheadListener{ public static final String DESTROY = "destroy"; public static final String MAXIMIZED = "MAXIMIZED"; public static final String MINIMIZED = "MINIMIZED"; public static final String STATE = "State"; private TextVIEw textVIEw; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Chathead.getInstance().setChatheadListener(this); setContentVIEw(R.layout.float_body); textVIEw = (TextVIEw) findVIEwByID(R.ID.root_text); } @OverrIDe public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK || event.getKeyCode() == KeyEvent.KEYCODE_HOME) { finish(); return true; } return super.dispatchKeyEvent(event); } @OverrIDe protected voID onStart() { super.onStart(); Intent destroy = new Intent(DESTROY); destroy.putExtra(STATE, MAXIMIZED); LocalbroadcastManager.getInstance(this).sendbroadcast(destroy); } @OverrIDe protected voID onDestroy() { Intent destroy = new Intent(DESTROY); destroy.putExtra(STATE, MINIMIZED); LocalbroadcastManager.getInstance(this).sendbroadcast(destroy); super.onDestroy(); } @OverrIDe public voID onChatheadClick(headModel headModel) { //method from my interface if(textVIEw!=null){ textVIEw.setText(headModel.getVisitorname()+""); } }}
更新(2016年4月4日)
主要活动
@OverrIDeprotected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); button_start = (button) findVIEwByID(R.ID.button_start); button_stop = (button) findVIEwByID(R.ID.button_stop); Intent intent = new Intent(this, MainActivity.class); PendingIntent resultPendingIntent = PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); Notification notification = Chathead.createNotification( this, "Chat head", "Service Running", R.drawable.ic_androID_red_500_48dp, resultPendingIntent); VIEw maxVIEw = LayoutInflater.from(this).inflate(R.layout.chat_head_recycler, null); VIEw minVIEw = LayoutInflater.from(this).inflate(R.layout.chat_head_vIEw, null); chathead = Chathead.createInstance(this, maxVIEw, minVIEw, NOTIFICATION_ID, notification, new ChatheadOrIEntationListener() { @OverrIDe public voID beforeOrIEntationChange(Chathead chathead) { Toast.makeText(MainActivity.this, "OrIEntation Change Start", Toast.LENGTH_SHORT).show(); } @OverrIDe public voID afterOrIEntationChange(Chathead chathead) { Toast.makeText(MainActivity.this, "OrIEntation Change End", Toast.LENGTH_SHORT).show(); } }); button_start.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw v) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { startChatheadForAboveAndroIDL(); } else { chathead.startService(); } } }); button_stop.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw v) { chathead.stopService(); } });}@TargetAPI(Build.VERSION_CODES.M)public voID startChatheadForAboveAndroIDL() { if (!Settings.canDrawOverlays(this)) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackagename())); startActivityForResult(intent, PERMISSION_REQUEST_CODE); } else { chathead.startService(); }}
Chathead类
public class Chathead{ private final VIEw maxVIEw, minVIEw; private final Context context; private final Notification notification; private final int notificationID; private static Chathead chathead; private static State state; private final ChatheadOrIEntationListener chatheadOrIEntationListener; private float ratioY = 0; private float olDWIDth = 0; private float oldX = 0; private boolean confChange = false; private static ChatheadListener chatheadListener; private static final String TAG = "Chathead"; private FragmentTransaction fragmentTransaction; /** * * @return The maxVIEw of the chathead which is assigned through the * {@link #createInstance} method. */ public VIEw getMaxVIEw() { return chathead.maxVIEw; } /** * * Creates a Singleton of the floating Window * * @param context The application context * @param maxVIEw The maxVIEw VIEw, upon clicking it the body is to be opened * @param notificationID The notificationID for your notification * @param notification The notification which is displayed for the foreground service * @param chatheadOrIEntationListener The {@link ChatheadOrIEntationListener} interface * with callbacks which are called when orIEntation changes. * @return A floating Window * */ public static synchronized Chathead createInstance(Context context, VIEw maxVIEw, VIEw minVIEw, int notificationID, Notification notification, ChatheadOrIEntationListener chatheadOrIEntationListener) { if (chathead == null) { chathead = new Chathead(context, maxVIEw, minVIEw, notificationID, notification, chatheadOrIEntationListener); } return chathead; } /** * * Creates a Singleton of the floating Window * * @param context The application context * @param maxVIEw The maxVIEw VIEw, upon clicking it the body is to be opened * @param notificationID The notificationID for your notification * @param notification The notification which is displayed for the foreground service * @return A floating Window * */ public static synchronized Chathead createInstance(Context context, VIEw maxVIEw, VIEw minVIEw, int notificationID, Notification notification) { if (chathead == null) { chathead = new Chathead(context, maxVIEw, minVIEw, notificationID, notification, new ChatheadOrIEntationListener() { @OverrIDe public voID beforeOrIEntationChange(Chathead chathead) { Log.d(TAG, "beforeOrIEntationChange"); } @OverrIDe public voID afterOrIEntationChange(Chathead chathead) { Log.d(TAG, "afterOrIEntationChange"); } }); } return chathead; } /** * @return The same instance of floating Window, which has been created through * {@link #createInstance}. Don't call this method before createInstance */ static synchronized Chathead getInstance() { if (chathead == null) { throw new NullPointerException("Chathead not initialized! " + "First call createInstance method, then to access " + "Chathead in any other class call getInstance()"); } return chathead; } private Chathead(Context context, VIEw maxVIEw, VIEw minVIEw, int notificationID, Notification notification, ChatheadOrIEntationListener chatheadOrIEntationListener) { this.maxVIEw = maxVIEw; this.minVIEw = minVIEw; this.context = context; this.notification = notification; this.notificationID = notificationID; this.chatheadOrIEntationListener = chatheadOrIEntationListener; } /** * Starts the service and adds it to the screen */ public voID startService() { Intent intent = new Intent(context, ChatheadService.class); context.startService(intent); } /** * Stops the service and removes it from the screen */ public voID stopService() { Intent intent = new Intent(context, ChatheadService.class); context.stopService(intent); } /** * * Helper method for notification creation. * * @param context * @param contentTitle * @param contentText * @param notificationIcon * @param contentIntent * @return Notification for the Service */ public static Notification createNotification(Context context, String contentTitle, String contentText, int notificationIcon, PendingIntent contentIntent) { return new NotificationCompat.Builder(context) .setContentTitle(contentTitle) .setContentText(contentText) .setSmallicon(notificationIcon) .setContentIntent(contentIntent).build(); } public static class ChatheadService extends Service { private WindowManager windowManager; private WindowManager.LayoutParams params; private linearLayout mlinearLayout; GestureDetectorCompat gestureDetectorCompat; displayMetrics metrics; private boolean dIDFling; private int[] clickLocation = new int[2]; private LocalbroadcastManager localbroadcastManager; private RecyclerVIEw recyclerVIEw; private relativeLayout rProgress, rSingleheadCon; @Nullable @OverrIDe public IBinder onBind(Intent intent) { return null; } @OverrIDe public voID onConfigurationChanged(Configuration newConfig) { if (newConfig.orIEntation == Configuration.ORIENTATION_LANDSCAPE || newConfig.orIEntation == Configuration.ORIENTATION_PORTRAIT) { int[] location = new int[2]; mlinearLayout.getLocationOnScreen(location); chathead.olDWIDth = metrics.wIDthPixels; chathead.confChange = true; chathead.oldX = location[0]; chathead.ratioY = (float) (location[1]) / (float) metrics.heightPixels; chathead.chatheadOrIEntationListener.beforeOrIEntationChange(chathead); chathead.stopService(); chathead.startService(); chathead.chatheadOrIEntationListener.afterOrIEntationChange(chathead); } } public int onStartCommand(Intent intent, int flags, int startID) { Log.d(TAG, "onStartCommand"); metrics = new displayMetrics(); windowManager.getDefaultdisplay().getMetrics(metrics); startForeground(chathead.notificationID, chathead.notification); return START_STICKY; } @OverrIDe public voID onCreate() { super.onCreate(); Log.d(TAG, "onCreate"); localbroadcastManager = LocalbroadcastManager.getInstance(this); localbroadcastManager.registerReceiver(receiver, new IntentFilter(MyActivity.DESTROY)); recyclerVIEw = (RecyclerVIEw) chathead.maxVIEw.findVIEwByID(R.ID.rv_heads); recyclerVIEw.setLayoutManager(new linearlayoutmanager( this, linearlayoutmanager.HORIZONTAL, false)); rProgress = (relativeLayout) chathead.minVIEw.findVIEwByID(R.ID.head_progress); rSingleheadCon = (relativeLayout) chathead.minVIEw.findVIEwByID(R.ID.head_vIEw_con); mlinearLayout = new linearLayout(getApplicationContext()); gestureDetectorCompat = new GestureDetectorCompat( chathead.context, new GestureDetector.SimpleOnGestureListener() { private int initialX; private int initialY; private float initialtouchX; private float initialtouchY; @OverrIDe public boolean onDown(MotionEvent event) { Log.d(TAG, "onDown"); initialX = params.x; initialY = params.y; initialtouchX = event.getRawX(); initialtouchY = event.getRawY(); dIDFling = false; return false; } @OverrIDe public voID onShowPress(MotionEvent e) { Log.d(TAG, "onShowPress"); chathead.minVIEw.setAlpha(0.8f); } @OverrIDe public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; params.wIDth = WindowManager.LayoutParams.WRAP_CONTENT; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.x = (initialX + (int) ((e2.getRawX() - initialtouchX))); params.y = (initialY + (int) ((e2.getRawY() - initialtouchY))); windowManager.updateVIEwLayout(mlinearLayout, params); return false; } @OverrIDe public boolean onSingleTapConfirmed(MotionEvent e) { Log.e(TAG, "Logging Chathead: onSingleTapConfirmed "); state = State.LOADING; rProgress.setVisibility(VIEw.VISIBLE); rSingleheadCon.setVisibility(VIEw.GONE); chathead.minVIEw.getLocationOnScreen(clickLocation); params.x = clickLocation[0]; params.y = clickLocation[1] - 36; windowManager.updateVIEwLayout(mlinearLayout, params); Intent intent = new Intent(ChatheadService.this,MyActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); return false; } @OverrIDe public boolean onDoubleTap(MotionEvent e) { chathead.stopService(); return false; } @OverrIDe public boolean onFling(MotionEvent e1, MotionEvent e2, float veLocityX, float veLocityY) { Log.d(TAG, "onFling"); dIDFling = true; int newX = params.x; if (newX > (metrics.wIDthPixels / 2)) params.x = metrics.wIDthPixels; else params.x = 0; windowManager.updateVIEwLayout(mlinearLayout, params); return false; } }); mlinearLayout.setorIEntation(linearLayout.VERTICAL); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); metrics = new displayMetrics(); windowManager.getDefaultdisplay().getMetrics(metrics); params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); params.gravity = Gravity.top | Gravity.left; if (chathead.confChange) { chathead.confChange = false; if (chathead.oldX < (chathead.olDWIDth / 2)) { params.x = 0; } else { params.x = metrics.wIDthPixels; } params.y = (int) (metrics.heightPixels * chathead.ratioY); } else { params.x = metrics.wIDthPixels; params.y = 0; } chathead.minVIEw.setontouchListener(new VIEw.OntouchListener() { @OverrIDe public boolean ontouch(VIEw v, MotionEvent event) { gestureDetectorCompat.ontouchEvent(event); if (event.getAction() == MotionEvent.ACTION_UP) { chathead.minVIEw.setAlpha(1.0f); if (!dIDFling) { Log.d(TAG, "ACTION_UP"); int newX = params.x; if (newX > (metrics.wIDthPixels / 2)) { params.x = metrics.wIDthPixels; }else { params.x = 0; windowManager.updateVIEwLayout(mlinearLayout, params); } } } return true; } }); windowManager.addVIEw(mlinearLayout, params); mlinearLayout.setFocusable(true); linearLayout.LayoutParams headParams = new linearLayout.LayoutParams( linearLayout.LayoutParams.WRAP_CONTENT, linearLayout.LayoutParams.WRAP_CONTENT); headParams.gravity = Gravity.top | Gravity.RIGHT; mlinearLayout.addVIEw(chathead.minVIEw, headParams); } private voID minimiseChathead() { state = State.MINIMIZED; rProgress.setVisibility(VIEw.GONE); rSingleheadCon.setVisibility(VIEw.VISIBLE); params.x = clickLocation[0]; params.y = clickLocation[1] - 36; params.wIDth = WindowManager.LayoutParams.WRAP_CONTENT; params.height = WindowManager.LayoutParams.WRAP_CONTENT; mlinearLayout.setFocusable(true); mlinearLayout.removeAllVIEws(); linearLayout.LayoutParams headParams = new linearLayout.LayoutParams( linearLayout.LayoutParams.WRAP_CONTENT, linearLayout.LayoutParams.WRAP_CONTENT); headParams.gravity = Gravity.top | Gravity.RIGHT; mlinearLayout.addVIEw(chathead.minVIEw, headParams); mlinearLayout.setTag("IMAGEVIEW_TAG"); //Todo close activity windowManager.updateVIEwLayout(mlinearLayout, params); } private voID maximiseChathead() { state = State.MAXIMIZED; params.x = metrics.wIDthPixels; params.y = 0;// params.flags = params.flags & ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; params.wIDth = WindowManager.LayoutParams.MATCH_PARENT; params.height = WindowManager.LayoutParams.WRAP_CONTENT;// chathead.body.setVisibility(VIEw.VISIBLE); List<headModel> heads = new ArrayList<>(); heads.add(new headModel("chat1")); heads.add(new headModel("chat2")); heads.add(new headModel("chat3")); final ChatheadsAdapter chatheadsAdapter = new ChatheadsAdapter(chathead.context, heads); recyclerVIEw.setAdapter(chatheadsAdapter); chatheadsAdapter.setonlinkClickListener(new ChatheadsAdapter.OnlinkClickListener() { @OverrIDe public voID onSingleTapListener(final headModel headModel, final int position) { if(state==State.MAXIMIZED){ if(chatheadListener!=null){ chatheadListener.onChatheadClick(headModel); }else{ maximiseChathead(); } }else if(state==State.MINIMIZED){ maximiseChathead(); } } @OverrIDe public voID onDoubleTapListener(final headModel headModel, final int position) { chatheadsAdapter.getheads().remove(position); chatheadsAdapter.notifyItemRemoved(position); } });// mlinearLayout.setFocusable(true); mlinearLayout.removeAllVIEws(); linearLayout.LayoutParams headParams = new linearLayout.LayoutParams( linearLayout.LayoutParams.MATCH_PARENT, linearLayout.LayoutParams.WRAP_CONTENT); headParams.gravity = Gravity.top | Gravity.RIGHT; mlinearLayout.addVIEw(chathead.maxVIEw, headParams); windowManager.updateVIEwLayout(mlinearLayout, params); } public voID onDestroy() { super.onDestroy(); localbroadcastManager.unregisterReceiver(receiver); if (mlinearLayout != null) { mlinearLayout.removeAllVIEws(); windowManager.removeVIEw(mlinearLayout); } stopForeground(true); } private final broadcastReceiver receiver = new broadcastReceiver() { @OverrIDe public voID onReceive(Context context, Intent intent) { String bCast = intent.getStringExtra(MyActivity.STATE); Log.e(TAG, "Logging Chathead: onReceive "+bCast); if(bCast.equals(MyActivity.MAXIMIZED)){ maximiseChathead(); }else if(bCast.equals(MyActivity.MINIMIZED)){ minimiseChathead(); } } }; } voID setChatheadListener(ChatheadListener chatheadListener) { Chathead.chatheadListener = chatheadListener; } public static State getState() { return state; } private enum State { MAXIMIZED, MINIMIZED, LOADING }}
表现
<service androID:name="com.maavratech.chatheads.Chathead$ChatheadService" androID:exported="true"/><activity androID:name=".MyActivity" androID:label="@string/app_name" androID:noHistory="true" androID:launchMode="singleTask" androID:excludeFromrecents="true" androID:theme="@style/themeChathead"/>
MyActivity是一个带有按钮和文本视图的简单活动
2016年11月11日更新
在正常情况下cpu(用户空间)使用率为2%但是当我按下主页按钮并重新点击聊天头时cpu使用率跃升至7%.我认为7%是正常的,这不是问题的原因.
方法追踪
解决方法:
我认为这可能是Intent Flags的问题.必须尝试添加标志
Intent.FLAG_ACTIVITY_LAUCHED_FROM_HISTORY?我还注意到你在AndroIDManifest.xml中设置了androID:noHistory =“true”.这有必要吗?
希望以上可以解决您的问题.如果它不起作用,你可以上传一个简单版本的apk进行测试吗?
总结以上是内存溢出为你收集整理的android – 延迟从聊天头服务启动活动全部内容,希望文章能够帮你解决android – 延迟从聊天头服务启动活动所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)