工欲善其事必先利其器,磨刀不误砍柴工
最近打算去深读源码,感觉不画图去分析源码根本理不清,也说不清
UML是分析类和类的关系,具体的类内部貌似没有图形机制,没有条件就创造条件呗
借此机会本人自定义一套图形绘图表示规范,并恬不知耻地称为捷型图
目的为了明确各种元素的图形表示,来表述与分析源码具体运行逻辑
为了避免每张图都加个图例,这里成文统一描述一下
一、常用表示
1.访问限制类型
访问限制类型.png无形状限定,修饰中(左上角)见色如见人
2.常见修饰符
常见修饰符.png三角形,放在左上角
3.类相关
类相关.png4.方法与变量
成员及方法.png5.关联线
关联线.png表述无歧义情况下箭头,数字可略
6.uml线
uml.png二.其他不常用:
1.第一组
不常用的组合1.png//待续...
三、几个小例子说明一下
1.类例子
ActivityThread是一个public final的普通类
ApplicationThread 是一个private的内部类 , 并处于 ActivityThread中
例子.png
2.方法与变量例子
l方法与变量.png3.sendBroadcast的第一层关系
在Activity中调用sendBroadcast,会调用ContextWrapper的sendBroadcast方法
sendBroadcast会使用ContextWrapper的成员变量mBase的sendBroadcast方法
而mBase实际上来源于ContextImpl,而ContextImpl是一个Context类,
ContextImpl的sendBroadcast方法调用ActivityManagerNative.getDefault().broadcastIntent发送广播
这样就将工作焦点指向ActivityManagerNative,可以进行第二层的绘制,也就是分析
ActivityManagerNative,上面的四行话解释和下面的图你更喜欢哪个?
成年人的世界没有单选题,当然选择都要,图文结合,更能形象说明
广播第一层.png
4.捷型图
示例
绘图规范.png下图是基于下面类绘制的图形,有什么好的意见或建议欢迎留言,
目前使用processon在线绘图工具,以后有时间开发个小软件来绘制感觉挺不错,
再加个一键生成什么的就更棒了...
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: J:\\Java\\Android\\LeverUp\\TolyService\\app\\src\\main\\aidl\\com\\toly1994\\tolyservice\\IMusicPlayerService.aidl
*/
package com.toly1994.tolyservice;
// Declare any non-default types here with import statements
public interface IMusicPlayerService extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements com.toly1994.tolyservice.IMusicPlayerService {
private static final java.lang.String DESCRIPTOR = "com.toly1994.tolyservice.IMusicPlayerService";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.toly1994.tolyservice.IMusicPlayerService interface,
* generating a proxy if needed.
*/
public static com.toly1994.tolyservice.IMusicPlayerService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.toly1994.tolyservice.IMusicPlayerService))) {
return ((com.toly1994.tolyservice.IMusicPlayerService) iin);
}
return new com.toly1994.tolyservice.IMusicPlayerService.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
java.lang.String descriptor = DESCRIPTOR;
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
case TRANSACTION_stop: {
data.enforceInterface(descriptor);
this.stop();
reply.writeNoException();
return true;
}
case TRANSACTION_pause: {
data.enforceInterface(descriptor);
this.pause();
reply.writeNoException();
return true;
}
case TRANSACTION_start: {
data.enforceInterface(descriptor);
this.start();
reply.writeNoException();
return true;
}
case TRANSACTION_prev: {
data.enforceInterface(descriptor);
this.prev();
reply.writeNoException();
return true;
}
case TRANSACTION_next: {
data.enforceInterface(descriptor);
this.next();
reply.writeNoException();
return true;
}
case TRANSACTION_release: {
data.enforceInterface(descriptor);
this.release();
reply.writeNoException();
return true;
}
case TRANSACTION_isPlaying: {
data.enforceInterface(descriptor);
boolean _result = this.isPlaying();
reply.writeNoException();
reply.writeInt(((_result) ? (1) : (0)));
return true;
}
case TRANSACTION_seek: {
data.enforceInterface(descriptor);
int _arg0;
_arg0 = data.readInt();
this.seek(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_create: {
data.enforceInterface(descriptor);
java.util.List<java.lang.String> _arg0;
_arg0 = data.createStringArrayList();
this.create(_arg0);
reply.writeNoException();
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements com.toly1994.tolyservice.IMusicPlayerService {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
@Override
public void stop() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_stop, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void pause() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_pause, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void start() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_start, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void prev() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_prev, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void next() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_next, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void release() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_release, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public boolean isPlaying() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_isPlaying, _data, _reply, 0);
_reply.readException();
_result = (0 != _reply.readInt());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public void seek(int pre_100) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(pre_100);
mRemote.transact(Stub.TRANSACTION_seek, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
//加in
@Override
public void create(java.util.List<java.lang.String> filePaths) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStringList(filePaths);
mRemote.transact(Stub.TRANSACTION_create, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_stop = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_pause = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_start = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_prev = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_next = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_release = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
static final int TRANSACTION_isPlaying = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
static final int TRANSACTION_seek = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
static final int TRANSACTION_create = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
public void stop() throws android.os.RemoteException;
public void pause() throws android.os.RemoteException;
public void start() throws android.os.RemoteException;
public void prev() throws android.os.RemoteException;
public void next() throws android.os.RemoteException;
public void release() throws android.os.RemoteException;
public boolean isPlaying() throws android.os.RemoteException;
public void seek(int pre_100) throws android.os.RemoteException;
//加in
public void create(java.util.List<java.lang.String> filePaths) throws android.os.RemoteException;
}
网友评论