参考:https://blog.csdn.net/u013356254/article/details/52287794

实现基本跟链接相同,不同只出在于WindowManager.LayoutParams的type设为了WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, 按照参考链接设置TYPE_SYSTEM_ERROR运行时会报错,

android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@398b86a -- permission denied for window type 2010

源码如下:
1.MainActivity

package com.example.zujian;import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.provider.Settings;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);permission();}@Overrideprotected void onResume() {super.onResume();}public void onClick(View view) {new Thread(new Runnable() {WindowManager wm;TextView tv;int width;int height;@RequiresApi(api = Build.VERSION_CODES.O)@Overridepublic void run() {Looper.prepare();wm = (WindowManager) getSystemService(WINDOW_SERVICE);final View view1 = View.inflate(MainActivity.this, R.layout.item, null);tv = view1.findViewById(R.id.tv);final WindowManager.LayoutParams params = new WindowManager.LayoutParams();params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;params.width = (int)(60 * getResources().getDisplayMetrics().density);params.height = (int)(60 * getResources().getDisplayMetrics().density);params.gravity = Gravity.START | Gravity.TOP;params.format = PixelFormat.TRANSPARENT;width = wm.getDefaultDisplay().getWidth();height = wm.getDefaultDisplay().getHeight();params.y = height / 2 - params.height / 2;wm.addView(view1, params);view1.setOnTouchListener(new View.OnTouchListener() {private int x, y;@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {switch (motionEvent.getAction()) {case MotionEvent.ACTION_DOWN:x = (int) motionEvent.getRawX();y = (int) motionEvent.getRawY();break;case MotionEvent.ACTION_MOVE:int minX = (int) (motionEvent.getRawX() - x);int minY = (int) (motionEvent.getRawY() - y);params.x = Math.min(width - params.width, Math.max(0, minX + params.x));params.y = Math.min(height - params.height, Math.max(0, minY + params.y));wm.updateViewLayout(view1, params);x = (int) motionEvent.getRawX();y = (int) motionEvent.getRawY();break;case MotionEvent.ACTION_UP:if(params.x > 0 && params.x < width - params.width) {int x = params.x;if(x > (width - params.width) / 2) {params.x = width - params.width;}else {params.x = 0;}wm.updateViewLayout(view1, params);}else if(params.x == 0 || params.x == width - params.width) {Toast.makeText(MainActivity.this, "被电击了", Toast.LENGTH_SHORT).show();tv.setText("哇哇");}break;}return true;}});Looper.loop();}}).start();}public void permission(){if (Build.VERSION.SDK_INT >= 23) {if(!Settings.canDrawOverlays(this)) {Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);startActivity(intent);}}}
}

2.布局

  1. activity_main.xml

     <?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:onClick="onClick"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>
    
  2. item.xml

     <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/holo_blue_bright"><TextViewandroid:id="@+id/tv"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/app_name" /></LinearLayout>
    

3.AndroidManifest.xml

声明了使用SYSTEM_ALERT_WINDOW权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.zujian"><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

android-如何在子线程中更新ui相关推荐

  1. android 不能在子线程中更新ui的讨论和分析

    问题描述 做过android开发基本都遇见过 ViewRootImpl$CalledFromWrongThreadException,上网一查,得到结果基本都是只能在主线程中更改 ui,子线程要修改 ...

  2. 为什么不能在子线程中更新UI

    首先声明一点:子线程里面是可以更新UI的--创建一个空白的Activity,在其xml文件中放一个空白TextView,Java代码如下: @Override protected void onCre ...

  3. C#子线程中更新ui

    本文实例总结了C#子线程更新UI控件的方法,对于桌面应用程序设计的UI界面控制来说非常有实用价值.分享给大家供大家参考之用.具体分析如下: 一般在winform C/S程序中经常会在子线程中更新控件的 ...

  4. Android子线程中更新UI的4种方法

    方法一:用Handler 1.主线程中定义Handler: Handler mHandler = new Handler() { @Override public void handleMessage ...

  5. 子线程中更新UI线程的三个方法

    1.通过handler方式,sendmessage. 多个类间传递比较麻烦,也懒的写... 2.线程中通过runOnUiThread() new Thread() { public void run( ...

  6. 【源码】让源码告诉你:为什么在子线程无法更新 UI 操作?

    博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载.本文由博主 威威喵 原创,请多支持与指教. 本文首发于此   博主:威威喵  |  博客主页:https://blog.csdn.net/ ...

  7. android 线程 界面,android开发教程之子线程中更新界面

    每个Handler对象与创建它的线程相关联,并且每个Handler对象只能与一个线程相关联. Handler一般有两种用途:1)执行计划任务,你可以再预定的实现执行某些任务,可以模拟定时器.2)线程间 ...

  8. Android中Handler的使用方法——在子线程中更新界面

    本文主要介绍Android的Handler的使用方法.Handler可以发送Messsage和Runnable对象到与其相关联的线程的消息队列.每个Handler对象与创建它的线程相关联,并且每个Ha ...

  9. Android利用Looper在子线程中改变UI

    MainActivity如下: package cn.testlooper; import android.app.Activity; import android.os.Bundle; import ...

最新文章

  1. 1132 Cut Integer
  2. 运维基础-文件权限管理
  3. php索引数组相等,php二维数组中子数组的某一键相等,其余键值求和
  4. 不属于html5表单元素的是,HTML5 表单元素
  5. 作者:​邓波(1973-),男,博士,北京系统工程研究所研究员。
  6. 面试准备每日五题:C++(四)——typedefdefine、指针常量、队列栈、地址赋值、C和C++结构体
  7. wamp怎么安装mysql服务器_使用WAMPServer套件可安装Apache服务器和MySQL服务器
  8. 转:Scrapy(爬虫框架)入门教程
  9. 数据结构:树(Tree)【详解】
  10. 发票:企业级发票服务开放平台
  11. 在JSP打开EXCEL文件
  12. Jenkins使用FTP上传文件报错问题处理
  13. 手机QQ山寨微信 3万网友愤愤不平
  14. java poi 导出excel设置数据有效性
  15. fiddler抓取谷歌浏览器的包_fiddler抓不到chrome浏览器的请求
  16. Python基础必掌握的Traceback回溯机制操作详解
  17. 简单了解Linux操作系统中的防火墙软件及其部署案例解析
  18. Amazon EKS基于GitLab的CICD实践一 GitLab的部署和配置篇
  19. 微信小程序使用canvas画图并保存到手机相册踩坑总结
  20. MySQL--事务回滚机制与原理

热门文章

  1. 星火计划ROS机器人Spark
  2. uboot下载与安装
  3. UITextField shouldChangeCharactersInRange获取实时数据并执行联想搜索和搜索
  4. python石头剪刀布程序_一个python石头剪刀布送给大家
  5. Nebu6月头条 | KubeCon落幕;Pivotal将亮相可信云;AWS降价49%取悦中国市场
  6. linux发包命令是什么,Linux tcpreplay 命令用法详解-Linux命令大全(手册)
  7. Windows10+GTX980Mcuda10+cudnn7.4.1+VS2017+darkent-yolov3编译详解
  8. 网易大佬叙述APP功能测试要点
  9. ubuntu远程桌面win10,ubuntu远程桌面ubuntu(亲测有效)
  10. 美团面试之Hr面,不会套路把我坑惨了......