首页 文章 精选 留言 我的

精选列表

搜索[知识管理],共10000篇文章
优秀的个人博客,低调大师

Docker背后的内核知识:命名空间资源隔离---亲测

参考URL: https://linux.cn/article-5057-1.html 实现代码(网络和用户空间只是看懂了) 实际上,Linux内核实现namespace的主要目的就是为了实现轻量级虚拟化(容器)服务。在同一个namespace下的进程可以感知彼此的变化,而对外界的进程一无所知。这样就可以让容器中的进程产生错觉,仿佛自己置身于一个独立的系统环境中,以此达到独立和隔离的目的。 需要说明的是,本文所讨论的namespace实现针对的均是Linux内核3.8及其以后的版本。 Namespace 系统调用参数 隔离内容 UTS CLONE_NEWUTS 主机名与域名 IPC CLONE_NEWIPC 信号量、消息队列和共享内存 PID CLONE_NEWPID 进程编号 Network CLONE_NEWNET 网络设备、网络栈、端口等等 Mount CLONE_NEWNS 挂载点(文件系统) User CLONE_NEWUSER 用户和用户组 #define _GNU_SOURCE #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <sched.h> #include <signal.h> #include <unistd.h> #define STACK_SIZE (1024 * 1024) static char child_stack[STACK_SIZE]; char* const child_args[] = {"/bin/bash", NULL}; int child_main(void* args) { printf("run in child process!\n"); sethostname("Changens", 12); execv(child_args[0], child_args); return 1; } int main() { printf("programe beginning....\n"); int child_pid = clone(child_main, child_stack+STACK_SIZE, CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWUTS|SIGCHLD, NULL); waitpid(child_pid, NULL, 0); printf("exited.\n"); return 0; }

优秀的个人博客,低调大师

Android--手机卫士涉及的知识点总结(三)

可扩展的ListView(ExpandableListView控件) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public class QuerryUsualNumber extends Activity { private ExpandableListView exl_listview; private SQLiteDatabase db; private TextView tv; private MyExpandableAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); db=SQLiteDatabase.openDatabase( "/data/data/com.cca.mobilephone/files/commonnum.db" , null , SQLiteDatabase.OPEN_READONLY); setContentView(R.layout.activity_querryusualnumber); exl_listview = (ExpandableListView) findViewById(R.id.exl_listview); adapter = new MyExpandableAdapter(); //设置适配器 exl_listview.setAdapter(adapter); //孩子被点击的监听器 exl_listview.setOnChildClickListener( new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { //点击条目获得数据库返回的数据,并分割提取号码进行拨号 String data=UsualNumberDao.getChildrenNameByPosition(db, groupPosition, childPosition); String datas[]=data.split( "\n" ); String name=datas[ 0 ]; String number=datas[ 1 ]; Toast.makeText(getApplicationContext(), groupPosition+ "--" +childPosition+ ":" +name+ ":" +number, 0 ).show(); //点击之后进行拨打指定号码的电话 Intent intent = new Intent(); intent.setAction(Intent.ACTION_CALL); intent.setData(Uri.parse( "tel:" +number)); startActivity(intent); return true ; } }); } 适配器 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 private class MyExpandableAdapter extends BaseExpandableListAdapter{ /** * 获取分组的个数 */ @Override public int getGroupCount() { return UsualNumberDao.getGroupCount(db); } /** * 获取每个分组的孩子的个数 */ @Override public int getChildrenCount( int groupPosition) { return UsualNumberDao.getChildGroupCount(db,groupPosition); } @Override public Object getGroup( int groupPosition) { return null ; } @Override public Object getChild( int groupPosition, int childPosition) { return null ; } @Override public long getGroupId( int groupPosition) { return 0 ; } @Override public long getChildId( int groupPosition, int childPosition) { return 0 ; } @Override public boolean hasStableIds() { return false ; } /** * 返回每个分组的view对象 */ @Override public View getGroupView( int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { //TextView tv; if (convertView== null ){ tv= new TextView(QuerryUsualNumber. this ); } else { tv=(TextView) convertView; } tv.setTextSize( 25 ); tv.setTextColor(Color.RED); tv.setText( " " +UsualNumberDao.getNameByGroupCountposition(db,groupPosition)); return tv; } @Override public View getChildView( int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { if (convertView== null ){ tv= new TextView(QuerryUsualNumber. this ); } else { tv=(TextView) convertView; } tv.setTextSize( 20 ); tv.setTextColor(Color.BLACK); tv.setText( " " +UsualNumberDao.getChildrenNameByPosition(db,groupPosition, childPosition)); return tv; } @Override public boolean isChildSelectable( int groupPosition, int childPosition) { return true ; } } @Override protected void onDestroy() { super .onDestroy(); db.close(); } 接口回调解耦的应用(用短信备份加进度条对话框来举例) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 /** * 短信备份 * * @param view */ public void SMSBackUp(View view) { /** * 直接弹出一个进度条对话框 */ final ProgressDialog pb = new ProgressDialog( this ); pb.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pb.setMessage( "正在备份......" ); pb.show(); // show出来才能看得见 new Thread() { public void run() { boolean result = SMSTool.SmsBackup( new SMSTool.SmsBackupCallBack() { /** * 接口里面的方法 */ @Override public void callBackprogress( int progress) { pb.setProgress(progress); } /** * 接口里面的方法 */ @Override public void callBackMax( int max) { pb.setMax(max); } }, ToolActivity. this , "back.xml" ); if (result) { ToastUtils.show(ToolActivity. this , "备份成功" ); } else { ToastUtils.show(ToolActivity. this , "备份失败" ); } pb.dismiss(); // 是否备份成功对话框都消失 }; }.start(); } 短信备份的逻辑: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 /** * 短信备份的工具类 * * @author Administrator * */ public class SMSTool { /** * 接口回调,定义一些抽象方法 * * @author Administrator * */ public interface SmsBackupCallBack { /** * 接口回调 * * @param max 最大值 * */ public abstract void callBackMax( int max); /** * 接口回调 * * @param progress */ public abstract void callBackprogress( int progress); } /** * 短信备份的业务逻辑 * * @param context 上下文 * * @param filename 存进的文件名 * * @return */ public static boolean SmsBackup(SmsBackupCallBack callBack, Context context, String filename) { try { ContentResolver resolver = context.getContentResolver(); Uri uri = Uri.parse( "content://sms/" ); Cursor cursor = resolver.query(uri, new String[] { "address" , "date" , "body" , "type" }, null , null , null ); File file = new File(Environment.getExternalStorageDirectory(), filename); FileOutputStream fos = new FileOutputStream(file); XmlSerializer serialer = Xml.newSerializer(); // 设置序列化参数 serialer.setOutput(fos, "utf-8" ); serialer.startDocument( "utf-8" , true ); serialer.startTag( null , "info" ); cursor.moveToNext(); int max = cursor.getCount(); int progress = 0 ; //接口方法 callBack.callBackMax(max); while (cursor.moveToNext()) { // cursor.moveToNext(); serialer.startTag( null , "sms" ); serialer.startTag( null , "address" ); String address = cursor.getString( 0 ); serialer.text(address); serialer.endTag( null , "address" ); serialer.startTag( null , "date" ); String date = cursor.getString( 1 ); serialer.text(date); serialer.endTag( null , "date" ); serialer.startTag( null , "body" ); String body = cursor.getString( 2 ); serialer.text(body); serialer.endTag( null , "body" ); serialer.startTag( null , "type" ); String type = cursor.getString( 3 ); serialer.text(type); serialer.endTag( null , "type" ); serialer.endTag( null , "sms" ); progress++; //接口的方法 callBack.callBackprogress(progress); } cursor.close(); serialer.startTag( null , "info" ); serialer.endDocument(); return true ; } catch (Exception e) { e.printStackTrace(); return false ; } } } 短信备份常见错误 org.kxml2.io.KXmlSerializer.text(KXmlSerializer.java:536) 这是因为短信的内容中存在着搜狗输入法的一些表情,无法识别,只要把带有表情符号的短信删除掉就可以成功备份 java.io.FileNotFoundException: /storage/emulated/0/backup.xml: 07-22 10:56:50.440: W/System.err(305): at open failed: EACCES (Permission denied) 没有权限齐全,短信的读写,sd卡、内存卡的读写权限等 listview的优化:四大原则 1、时间换空间 (牺牲时间换取空间,流的读写) 2、空间换时间 (把文件的路径存进数据库,以后查询就快很多,Android下的图库应用检索) 3、时间换时间 (开机启动速度的优化) 4、空间换空间 把内存换成硬盘,或者把硬盘换成内存 获取手机中所有应用程序的关键信息以List 返回List集合对象 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 public class AppManagerInfos { @SuppressWarnings ( "unused" ) public static List getAppManagerInfos(Context context) { List appinfos = new ArrayList(); PackageManager pm = context.getPackageManager(); //获取安装在手机上的应用程序 List<packageinfo> infos = pm.getInstalledPackages( 0 ); for (PackageInfo appInfo : infos) { AppInfo info = new AppInfo(); // 获得包名 String packagename = appInfo.packageName; info.setPakageName(packagename); // 获得应用名称 String appname = appInfo.applicationInfo.loadLabel(pm).toString(); info.setAppname(appname); // 获得应用图标 Drawable icon = appInfo.applicationInfo.loadIcon(pm); info.setIcon(icon); // 获得应用app的绝对路径 String path = appInfo.applicationInfo.sourceDir; info.setPath(path); // 获得应用app的大小 File file = new File(path); long size = file.length(); String sizedata = Formatter.formatFileSize(context, size); info.setSize(size); int flag = appInfo.applicationInfo.flags; if ((flag & ApplicationInfo.FLAG_SYSTEM) == 0 ) { // 用户应用 info.setUserapp( true ); } else { // 系统应用 info.setUserapp( false ); } if ((flag & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0 ) { // 存在手机内存 info.setInRom( true ); } else { // 存在sd内存卡 info.setInRom( false ); } appinfos.add(info); } return appinfos; } } </packageinfo></appinfo></appinfo></appinfo> 把不同集合数据展示到ListView中 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 public class AppManagerActivity extends Activity { private TextView tv_shji_byte; private TextView tv_sd_byte; private ListView lv_listview; private LinearLayout ll_loading; private List infos; private List userapp; private List systemapp; private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { lv_listview.setAdapter( new MyAppManagerAdapter()); ll_loading.setVisibility(View.INVISIBLE); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_app_manager); tv_shji_byte = (TextView) findViewById(R.id.tv_shji_byte); tv_sd_byte = (TextView) findViewById(R.id.tv_sd_byte); lv_listview = (ListView) findViewById(R.id.lv_listview); ll_loading = (LinearLayout) findViewById(R.id.ll_loading); userapp = new ArrayList(); systemapp = new ArrayList(); File datafile = Environment.getDataDirectory(); long datasize = datafile.getFreeSpace(); File sdfile = Environment.getExternalStorageDirectory(); long sdsize = sdfile.getFreeSpace(); tv_shji_byte.setText( "手机可用内存" + Formatter.formatFileSize( this , datasize)); tv_sd_byte.setText( "sd卡可用内存" + Formatter.formatFileSize( this , sdsize)); fillData(); } /** * 填充数据 */ private void fillData() { new Thread() { public void run() { infos = AppManagerInfos .getAppManagerInfos(AppManagerActivity. this ); for (AppInfo info : infos) { if (info.isUserapp()) { // 用户程序 userapp.add(info); } else { systemapp.add(info); // 系统程序 } } handler.sendEmptyMessage( 0 ); }; }.start(); } private class MyAppManagerAdapter extends BaseAdapter { @Override public int getCount() { return userapp.size() + systemapp.size() + 2 ; } @Override public View getView( int position, View convertView, ViewGroup parent) { View view; HoldView holder; if (convertView != null && convertView instanceof RelativeLayout) { view = convertView; holder = (HoldView) view.getTag(); } else { holder = new HoldView(); view = View.inflate(AppManagerActivity. this , R.layout.item_app_manager, null ); holder.app_name = (TextView) view.findViewById(R.id.app_name); holder.app_location = (TextView) view .findViewById(R.id.app_location); holder.app_icon = (ImageView) view.findViewById(R.id.app_icom); holder.app_size = (TextView) view.findViewById(R.id.app_size); view.setTag(holder); } AppInfo info; if (position == 0 ) { // 显示textView用户程序 TextView tv_user = new TextView(AppManagerActivity. this ); tv_user.setTextSize( 15 ); tv_user.setBackgroundColor(Color.GREEN); tv_user.setTextColor(Color.BLACK); tv_user.setText( "用户程序" + userapp.size() + "个" ); return tv_user; } else if (position == userapp.size() + 1 ) { TextView tv_system = new TextView(AppManagerActivity. this ); tv_system.setTextSize( 15 ); tv_system.setBackgroundColor(Color.GREEN); tv_system.setTextColor(Color.BLACK); tv_system.setText( "系统程序" + systemapp.size() + "个" ); return tv_system; } else if (position < userapp.size() + 1 ) { // 用户程序 info = userapp.get(position - 1 ); } else { // 系统程序 info = systemapp.get(position - 2 - userapp.size()); } holder.app_name.setText(info.getAppname()); holder.app_icon.setImageDrawable(info.getIcon()); holder.app_size.setText(Formatter.formatFileSize( AppManagerActivity. this , info.getSize()) + "M" ); if (info.isInRom()) { holder.app_location.setText( "手机内存" ); } else { holder.app_location.setText( "sd卡储存" ); } return view; } @Override public Object getItem( int position) { return null ; } @Override public long getItemId( int position) { return 0 ; } private class HoldView { TextView app_name; TextView app_location; ImageView app_icon; TextView app_size; } } </appinfo></appinfo></appinfo></appinfo></appinfo> 设置listview属性可使其快速滚动 ? 1 android:fastScrollEnabled= "true" 在listview滚动时悬浮标识符 ? 1 2 3 4 5 在帧布局中加入一个TextView <textview android:background= "#00FF00" android:id= "@+id/tv_biaoshi" android:layout_height= "wrap_content" android:layout_width= "match_parent" android:text= "用户程序" android:textcolor= "#000000" android:textsize= "15sp" > </textview> 不过设置属性时需要和之前区分系统用户时的属性相同,背景色、字体、大小,这样才可以重合 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 TextView tv_biaoshi=(TextView) findViewById(R.id.tv_biaoshi); /** * 给listview注册一个滚动监听器 */ lv_listview.setOnScrollListener( new OnScrollListener() { /** * 当状态发生改变时执行此方法 */ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } /** * 当listview滚动时执行此方法 */ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem>userapp.size()){ tv_biaoshi.setText( "系统程序" +systemapp.size()+ "个" ); } else { tv_biaoshi.setText( "用户程序" +userapp.size()+ "个" ); } } }); 悬浮窗体的创建使用(轻量级的对话框,内存开销比对话框小,灵活)漂浮的容器,在activity上方 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 //点击条目弹出悬浮窗体 TextView convertView= new TextView(AppManagerActivity. this ); convertView.setTextSize( 15 ); convertView.setTextColor(Color.RED); convertView.setText(info.getPakageName()); popupwindow = new PopupWindow(convertView, 300 , 100 ); popupwindow.setBackgroundDrawable( new ColorDrawable(Color.GREEN)); //获取点击的条目view对象到窗体的宽高(左上对齐)存在location中x、y int []location= new int [ 2 ]; view.getLocationInWindow(location); popupwindow.showAtLocation(parent, Gravity.TOP+Gravity.LEFT, 80 , location[ 1 ]); 不过一般都是自定义悬浮窗体 ? 1 View convertView=View.inflate(getApplicationContext(), R.layout.item_app_popupwindow, null ); 布局文件item.app.popupwindow.xml ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <!--?xml version= "1.0" encoding= "utf-8" ?--> <linearlayout android:background= "@drawable/tip_bg" android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:orientation= "horizontal" xmlns:android= "http://schemas.android.com/apk/res/android" > <linearlayout android:layout_height= "wrap_content" android:layout_marginleft= "5dp" android:layout_margintop= "5dp" android:layout_width= "wrap_content" android:orientation= "vertical" > <imageview android:layout_height= "wrap_content" android:layout_margintop= "5dp" android:layout_width= "wrap_content" android:src= "@drawable/my_user_exit" > <textview android:layout_height= "wrap_content" android:layout_marginbottom= "3dp" android:layout_width= "wrap_content" android:text= "启动" > </textview></imageview></linearlayout> <linearlayout android:layout_height= "wrap_content" android:layout_marginleft= "5dp" android:layout_margintop= "5dp" android:layout_width= "wrap_content" android:orientation= "vertical" > <imageview android:layout_height= "wrap_content" android:layout_margintop= "5dp" android:layout_width= "wrap_content" android:src= "@drawable/delete" > <textview android:layout_height= "wrap_content" android:layout_marginbottom= "3dp" android:layout_width= "wrap_content" android:text= "删除" > </textview></imageview></linearlayout> <linearlayout android:layout_height= "wrap_content" android:layout_marginleft= "5dp" android:layout_width= "wrap_content" android:orientation= "vertical" > <imageview android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:src= "@drawable/wx_share_friends" > <textview android:layout_height= "wrap_content" android:layout_marginbottom= "3dp" android:layout_width= "wrap_content" android:text= "分享" > </textview></imageview></linearlayout> <linearlayout android:layout_height= "wrap_content" android:layout_marginleft= "5dp" android:layout_margintop= "5dp" android:layout_width= "wrap_content" android:orientation= "vertical" > <imageview android:layout_height= "wrap_content" android:layout_margintop= "5dp" android:layout_width= "wrap_content" android:src= "@drawable/datasafety_item_icon_config" > <textview android:layout_height= "wrap_content" android:layout_marginbottom= "3dp" android:layout_width= "wrap_content" android:text= "信息" > </textview></imageview></linearlayout> </linearlayout> ? 1 2 3 4 5 6 7 保证窗体中只有一个悬浮窗体,每次弹出前执行判断;listview滚动时消失也执行此方法 public void dismissPopupwindow() { if (popupwindow!= null && popupwindow.isShowing()){ popupwindow.dismiss(); popupwindow= null ; } 动画的播放原理 ? 1 2 3 4 5 6 确定一个变化的函数: 根据这个函数 动态计算在某个时间应该显示什么画面 Canvas Bitmap 要求界面的窗体必须有背景,所以悬浮窗体必须设置背景才能启动动画 } 一键分享 ? 1 2 3 4 5 6 7 8 9 10 //发送纯文本 Intent intent= new Intent(); intent.setAction(Intent.ACTION_SEND); intent.addCategory( "android.intent.category.DEFAULT" ); intent.setType( "text/plain" ); //intent.setType("image/*");//图片 //intent.setType("video/*");//音频、视频 //intent.setType("*/*");//所有类型 intent.putExtra(Intent.EXTRA_TEXT, "请使用这款软件" ); startActivity(intent); 一键卸载 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 动态注册广播接收者 innerReceiver= new InnerUninstallAppReceiver(); IntentFilter filter= new IntentFilter(); filter.addAction(Intent.ACTION_PACKAGE_REMOVED); filter.addDataScheme( "package" ); registerReceiver(innerReceiver, filter); /** * 卸载软件程序后需要更新数据注册一个广播接收者 */ private void uninstallapp() { if (info.isUserapp()){ Intent intent= new Intent(); intent.setAction(Intent.ACTION_DELETE); intent.setData(Uri.parse( "package:" +info.getPakageName())); startActivity(intent); } else { ToastUtils.show( this , "应用程序需要root权限才能卸载" ); } } /** * 内部类,广播接收者,监听软件卸载的事件 * @author Administrator * */ private class InnerUninstallAppReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if (info.isUserapp()){ userapp.remove(info); } else { systemapp.remove(info); } adapter.notifyDataSetChanged(); } } 一键启动软件 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 /** * 打开软件的功能 */ public void openApp() { PackageManager pm=getPackageManager(); Intent intent=pm.getLaunchIntentForPackage(info.getPakageName()); if (intent!= null ){ startActivity(intent); } else { ToastUtils.show( this , "软件无法启动!" ); } } 查看应用程序信息(也可卸载应用程序:系统的设置卸载界面) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /** * 查看应用程序全部信息 */ private void showApp() { //查找上层应用程序源码 /* <category android:name="android.intent.category.DEFAULT"> <data android:scheme="package">*/ Intent intent = new Intent(); intent.setAction( "android.settings.APPLICATION_DETAILS_SETTINGS" ); intent.addCategory( "android.intent.category.DEFAULT" ); intent.setData(Uri.parse( "package:" +info.getPakageName())); startActivity(intent); } </data></category></action>

优秀的个人博客,低调大师

Android--手机卫士涉及的知识点总结(四)

获取手机所有正在运行的进程(返回的是List集合) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 package com.cca.mobilephone.engine; import java.util.ArrayList; import java.util.List; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import com.cca.mobilephone.domain.ProcessInfo; /** * 获取所有正在运行的进程信息 * @author Administrator * */ public class TaskInfoProvifer { public static List<processinfo> getRunningProcessInfo(Context context){ List<processinfo> process= new ArrayList<processinfo>(); ActivityManager am=(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); PackageManager pm=context.getPackageManager(); //获取正在运行的进程集合 List<runningappprocessinfo>processrunninginfoinfo=am.getRunningAppProcesses(); //遍历集合 for (RunningAppProcessInfo runninginfo:processrunninginfoinfo){ ProcessInfo processinfo= new ProcessInfo(); //进程包名 String packageName=runninginfo.processName; processinfo.setPackageName(packageName); long menSize=am.getProcessMemoryInfo( new int []{runninginfo.pid})[ 0 ]. getTotalPrivateDirty()* 1024 ; processinfo.setMenSize(menSize); try { PackageInfo packageinfo=pm.getPackageInfo(packageName, 0 ); //进程图标 Drawable icon=packageinfo.applicationInfo.loadIcon(pm); processinfo.setIcon(icon); //进程名称 String processName=packageinfo.applicationInfo.loadLabel(pm).toString(); processinfo.setProcessName(processName); // if ((packageinfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)!= 0 ){ //系统进程 processinfo.setUserProcess( false ); } else { //用户进程 processinfo.setUserProcess( true ); } } catch (NameNotFoundException e) { e.printStackTrace(); } process.add(processinfo); } return process; } } </runningappprocessinfo></processinfo></processinfo></processinfo> javabean类的信息 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package com.cca.mobilephone.domain; import android.graphics.drawable.Drawable; /** * 进程包含的信息 * @author Administrator * */ public class ProcessInfo { private String packageName; private String processName; private Drawable icon; private long menSize; private boolean userProcess; public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this .packageName = packageName; } public String getProcessName() { return processName; } public void setProcessName(String processName) { this .processName = processName; } public Drawable getIcon() { return icon; } public void setIcon(Drawable icon) { this .icon = icon; } public long getMenSize() { return menSize; } public void setMenSize( long menSize) { this .menSize = menSize; } public boolean isUserProcess() { return userProcess; } public void setUserProcess( boolean userProcess) { this .userProcess = userProcess; } } 区分用户进程和系统进程(这是耗时操作) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 List<processinfo> processinfo=TaskInfoProvifer.getRunningProcessInfo(getApplicationContext()); userprocess= new ArrayList<processinfo>(); systemprocess= new ArrayList<processinfo>(); for (ProcessInfo process:processinfo){ if (process.isUserProcess()){ //用户程序 userprocess.add(process); } else { //系统程序 systemprocess.add(process); } } //通知界面更新 handler.sendEmptyMessage( 0 ); </processinfo></processinfo></processinfo> 打开一个服务,内部注册一个广播接收者,监听锁屏清理进程 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 public class AutoKillService extends Service { private InnerScrrenOffReceiver receiver; private Timer timer; private TimerTask task; @Override public IBinder onBind(Intent intent) { return null ; } @Override public void onCreate() { super .onCreate(); receiver= new InnerScrrenOffReceiver(); IntentFilter filter= new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); registerReceiver(receiver, filter); /** * 常用定时器,可设置为定时清理的功能 */ timer= new Timer(); task= new TimerTask() { @Override public void run() { //System.out.println("每1秒执行一次"); //清理的逻辑 } }; timer.schedule(task, 0 , 1000 ); } @Override public void onDestroy() { super .onDestroy(); timer.cancel(); task.cancel(); unregisterReceiver(receiver); receiver= null ; } private class InnerScrrenOffReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //System.out.println("哈哈,屏幕锁屏了"); ActivityManager am=(ActivityManager) getSystemService(ACTIVITY_SERVICE); List<runningappprocessinfo> infos= am.getRunningAppProcesses(); for (RunningAppProcessInfo info:infos){ //杀死后台进程 am.killBackgroundProcesses(info.processName); } } } } </runningappprocessinfo> 如何创建一个widget只需要3步 1、定义一个广播接收者继承AppwidgetProvider 2、在清单文件中配置广播接收者 ? 1 2 3 4 5 6 <receiver android:name= "ExampleAppWidgetProvider" > <intent-filter> </action></intent-filter> <meta-data android:name= "android.appwidget.provider" android:resource= "@xml/example_appwidget_info" > </meta-data></receiver> 3、建立一个xml文件夹存放资源example_appwidget_info.xml ? 1 2 </appwidget-provider> 4、自定义布局example_appwidget的内容 生命周期: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 在手机桌面上创建第一个widget 11 - 05 00 : 46 : 24.817 : I/System.out( 1687 ): onreceive 接收到了系统的广播消息 11 - 05 00 : 46 : 24.817 : I/System.out( 1687 ): onenable (适合应用程序widget的初始化.) 11 - 05 00 : 46 : 24.817 : I/System.out( 1687 ): onreceive 接收到了系统的广播消息 11 - 05 00 : 46 : 24.817 : I/System.out( 1687 ): onupdate (只要有新的widget被创建都会调用onupdate方法) 11 - 05 00 : 46 : 27.347 : I/System.out( 1687 ): onreceive 接收到了系统的广播消息 如果界面上已经有一个widget被创建,再创建相同的widget 11 - 05 00 : 47 : 34.728 : I/System.out( 1687 ): onreceive 接收到了系统的广播消息 11 - 05 00 : 47 : 34.728 : I/System.out( 1687 ): onupdate 11 - 05 00 : 47 : 36.629 : I/System.out( 1687 ): onreceive 接收到了系统的广播消息 删除一个widget 11 - 05 00 : 48 : 48.019 : I/System.out( 1687 ): onreceive 接收到了系统的广播消息 11 - 05 00 : 48 : 48.019 : I/System.out( 1687 ): ondelete 最后一个widget被删除 11 - 05 00 : 49 : 25.710 : I/System.out( 1687 ): onreceive 接收到了系统的广播消息 11 - 05 00 : 49 : 25.710 : I/System.out( 1687 ): ondelete 11 - 05 00 : 49 : 25.710 : I/System.out( 1687 ): onreceive 接收到了系统的广播消息 11 - 05 00 : 49 : 25.710 : I/System.out( 1687 ): ondisabled (适合做应用程序扫尾的操作,) 总结: 不要记生命周期调用的先后顺序. ? 1 2 3 onenable 方法什么时候调用 ondisabled 方法什么时候调用 onupdate方法 在每次创建新的widget的时候都会调用 , 并且当时间片到的时候也会调用 创建widget模板 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public class MyWidget extends AppWidgetProvider { @Override public void onReceive(Context context, Intent intent) { //创建第一个桌面widget的时候调用 super .onReceive(context, intent); } //每次创建widget时都会调用 @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) { Intent intent= new Intent(context,UpdateWidgetService. class ); context.startService(intent); super .onUpdate(context, appWidgetManager, appWidgetIds); } //删除widget会调用 @Override public void onDeleted(Context context, int [] appWidgetIds) { super .onDeleted(context, appWidgetIds); } //对widget做初始化时调用 @Override public void onEnabled(Context context) { super .onEnabled(context); } //结束widget是调用,做扫尾工作 @Override public void onDisabled(Context context) { super .onDisabled(context); Intent intent= new Intent(context,UpdateWidgetService. class ); context.stopService(intent); } } 桌面启动服务定时更新widget ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class UpdateWidgetService extends Service { private Timer timer; private TimerTask task; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null ; } @Override public void onCreate() { super .onCreate(); timer= new Timer(); task= new TimerTask(){ @Override public void run() { System.out.println( "更新widget里面的内容" ); /* * 进程间通讯 */ ComponentName provider= new ComponentName(getApplicationContext(), MyWidget. class ); /* * 告诉桌面布局文件去哪里找 */ RemoteViews views= new RemoteViews(getPackageName(), R.layout.process_widget); views.setTextViewText(R.id.process_count, "正在运行的软件" +ProcessInfoUtils.getRunningProcessCount(getApplicationContext())+ "个" ); String availstr=Formatter.formatFileSize(getApplicationContext(), ProcessInfoUtils.getAvialRam(getApplicationContext())); views.setTextViewText(R.id.process_memory, "可用内存:" +availstr); am.updateAppWidget(provider, views); }}; timer.schedule(task, 0 , 5000 ); } @Override public void onDestroy() { super .onDestroy(); timer.cancel(); task.cancel(); timer= null ; task= null ; } } 逆向小助手的使用:反编译获取素材资源文件,everything可快速查找 反编译 拖拽到目录 多层显示的帧布局,功能多多 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <framelayout android:layout_height= "0dp" android:layout_weight= "1" android:layout_width= "match_parent" > <listview android:fastscrollenabled= "true" android:id= "@+id/lv_process_listview" android:layout_height= "match_parent" android:layout_width= "match_parent" > </listview> <linearlayout android:gravity= "center" android:id= "@+id/ll_loading" android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "vertical" android:visibility= "visible" > <progressbar android:layout_height= "wrap_content" android:layout_width= "wrap_content" > <textview android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:text= "正在加载中..." > </textview></progressbar></linearlayout> <textview android:background= "#00FF00" android:id= "@+id/tv_process_biaoshi" android:layout_height= "wrap_content" android:layout_width= "match_parent" android:text= "用户进程" android:textcolor= "#000000" android:textsize= "15sp" > </textview></framelayout> 杀死所有运行的进程 ? 1 2 3 4 5 6 7 8 ActivityManager am=(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<runningappprocessinfo> infos=am.getRunningAppProcesses(); for (RunningAppProcessInfo info:infos){ am.killBackgroundProcesses(info.processName); //参数为包名 } </runningappprocessinfo> 抽屉控件 (重下往上拉),也可指定拉升的高度 ? 1 2 3 4 5 6 7 8 9 <slidingdrawer android:content= "@+id/my_content" android:handle= "@+id/my_handle" android:layout_height= "match_parent" android:layout_width= "match_parent" > <imageview android:id= "@id/my_handle" android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:src= "@drawable/ic_launcher" > <linearlayout android:gravity= "center" android:id= "@id/my_content" android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:orientation= "vertical" > <textview android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:text= "我是一个" > <progressbar android:layout_height= "wrap_content" android:layout_width= "wrap_content" > </progressbar></textview></linearlayout> </imageview></slidingdrawer> 也可重右往左拉 ? 1 2 <slidingdrawer android:content= "@+id/my_content" android:handle= "@+id/my_handle" android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "horizontal" > </slidingdrawer> 界面的切换(一个切面不同的布局切换) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <!--?xml version= "1.0" encoding= "utf-8" ?--> <linearlayout android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "vertical" xmlns:android= "http://schemas.android.com/apk/res/android" > <linearlayout android:gravity= "center" android:layout_height= "wrap_content" android:layout_width= "match_parent" android:orientation= "horizontal" > <textview android:background= "@drawable/tab_left_pressed" android:gravity= "center_vertical" android:id= "@+id/app_unlock" android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:text= "未加锁软件" android:textsize= "20sp" > <textview android:background= "@drawable/tab_right_default" android:gravity= "center_vertical" android:id= "@+id/app_locked" android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:text= "已加锁软件" android:textsize= "20sp" > </textview></textview></linearlayout> <framelayout android:layout_height= "match_parent" android:layout_width= "match_parent" > <linearlayout android:id= "@+id/ll_loading" android:layout_gravity= "center" android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:orientation= "vertical" android:visibility= "visible" > <progressbar android:layout_gravity= "center" android:layout_height= "wrap_content" android:layout_width= "wrap_content" > <textview android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:text= "正在加载数据..." > </textview></progressbar></linearlayout> <linearlayout android:id= "@+id/ll_appunlock" android:layout_height= "wrap_content" android:layout_width= "match_parent" android:orientation= "vertical" > <textview android:id= "@+id/tv_unlock_count" android:layout_height= "wrap_content" android:layout_width= "match_parent" android:text= "未加锁软件" > <listview android:id= "@+id/lv_unlock" android:layout_height= "match_parent" android:layout_width= "match_parent" > </listview> </textview></linearlayout> <linearlayout android:id= "@+id/ll_applocked" android:layout_height= "wrap_content" android:layout_width= "match_parent" android:orientation= "vertical" android:visibility= "gone" > <textview android:id= "@+id/tv_locked_count" android:layout_height= "wrap_content" android:layout_width= "match_parent" android:text= "加锁软件" > <listview android:id= "@+id/lv_locked" android:layout_height= "match_parent" android:layout_width= "match_parent" > </listview> </textview></linearlayout> </framelayout> </linearlayout>

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册