Java原始碼閱讀繪圖規範手冊–[捷特版]

張風捷特烈發表於1970-01-01

工欲善其事必先利其器,磨刀不誤砍柴工

最近打算去深讀原始碼,感覺不畫圖去分析原始碼根本理不清,也說不清
UML是分析類和類的關係,具體的類內部貌似沒有圖形機制,沒有條件就創造條件唄
藉此機會本人自定義一套圖形繪圖表示規範,並恬不知恥地稱為捷型圖
目的為了明確各種元素的圖形表示,來表述與分析原始碼具體執行邏輯

為了避免每張圖都加個圖例,這裡成文統一描述一下


一、常用表示

1.訪問限制型別

無形狀限定,修飾中(左上角)見色如見人

訪問限制型別.png

2.常見修飾符

三角形,放在左上角

常見修飾符.png

3.類相關
類相關.png

4.方法與變數
成員及方法.png

5.關聯線

表述無歧義情況下箭頭,數字可略

關聯線.png

6.uml線
uml.png

二.其他不常用:

1.第一組
不常用的組合1.png

//待續…


三、幾個小例子說明一下

1.類例子
ActivityThread是一個public final的普通類ApplicationThread 是一個private的內部類 , 並處於 ActivityThread中複製程式碼
例子.png

2.方法與變數例子
l方法與變數.png

3.sendBroadcast的第一層關係
在Activity中呼叫sendBroadcast,會呼叫ContextWrapper的sendBroadcast方法sendBroadcast會使用ContextWrapper的成員變數mBase的sendBroadcast方法而mBase實際上來源於ContextImpl,而ContextImpl是一個Context類,ContextImpl的sendBroadcast方法呼叫ActivityManagerNative.getDefault().broadcastIntent傳送廣播  這樣就將工作焦點指向ActivityManagerNative,可以進行第二層的繪製,也就是分析ActivityManagerNative,上面的四行話解釋和下面的圖你更喜歡哪個?  成年人的世界沒有單選題,當然選擇都要,圖文結合,更能形象說明複製程式碼
廣播第一層.png

4.捷型圖示例

下圖是基於下面類繪製的圖形,有什麼好的意見或建議歡迎留言,
目前使用processon線上繪圖工具,以後有時間開發個小軟體來繪製感覺挺不錯,
再加個一鍵生成什麼的就更棒了…

繪圖規範.png
/* * 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 statementspublic 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;

}複製程式碼

來源:https://juejin.im/post/5c495893f265da616e4cc21b

相關文章