使用方法:

1无法再真机运行,需要在模拟机运行

 

2app在manifest要添加
1<uses-permission android:name="android.permission.INTERNET"/>

2<application android:debugable=" true"

 

3在测试的activity中使用:

(1)添加三行代码:

                    public void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);
 
          ViewServer.get(this).addWindow(this);
      }
 
      public void onDestroy() {
          super.onDestroy();
          ViewServer.get(this).removeWindow(this);
      }
 
      public void onResume() {
          super.onResume();
          ViewServer.get(this).setFocusedWindow(this);
      }

2)点击运行as项目,然后模拟器运行程序,

3tools--android--androiddevice monitor

(4)界面打开后,没有找到,搜索hierarachy view即可,本人亲测,没有问题

android studio上HierarchyViewer的使用实例_第1张图片android studio上HierarchyViewer的使用实例_第2张图片

直接上使用的源码:

创建ViewServer.java类(拷贝过去就可以):

package com.linzhi.receiver (替换) ;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewDebug;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 
*布局优化HierarchyViewer的类
 
*
 
* Created by sjy on 2017/5/2.
 */

public class ViewServer implements Runnable {
   
/**
    
* The default port used to startview servers.
     */
   
private static final int VIEW_SERVER_DEFAULT_PORT = 4939 ;
   
private static final int VIEW_SERVER_MAX_CONNECTIONS = 10 ;
   
private static final String BUILD_TYPE_USER = "user" ;

   
// Debug facility
   
private static final String LOG_TAG = "ViewServer" ;

   
private static final String VALUE_PROTOCOL_VERSION = "4" ;
   
private static final String VALUE_SERVER_VERSION = "4" ;

   
// Protocol commands
   
// Returns the protocol version
   
private static final String COMMAND_PROTOCOL_VERSION = "PROTOCOL" ;
   
// Returns the server version
   
private static final String COMMAND_SERVER_VERSION = "SERVER" ;
   
// Lists all of the available windows in thesystem
   
private static final String COMMAND_WINDOW_MANAGER_LIST = "LIST" ;
   
// Keeps a connection open and notifies when thelist of windows changes
   
private static final String COMMAND_WINDOW_MANAGER_AUTOLIST = "AUTOLIST" ;
   
// Returns the focused window
   
private static final String COMMAND_WINDOW_MANAGER_GET_FOCUS = "GET_FOCUS" ;

   
private ServerSocket mServer ;
   
private final int mPort ;

   
private Thread mThread ;
   
private ExecutorService mThreadPool ;

   
private final List mListeners =
           
new CopyOnWriteArrayList();

   
private final HashMap mWindows = new HashMap();
   
private final ReentrantReadWriteLock mWindowsLock = new ReentrantReadWriteLock();

   
private View mFocusedWindow ;
   
private final ReentrantReadWriteLock mFocusLock = new ReentrantReadWriteLock();

   
private static ViewServer sServer ;

   
/**
    
* Returns a unique instance of theViewServer. This method should only be
     * called from the main thread ofyour application. The server will have
     * the same lifetime as your process.
     *


     * If your application does not havethe android:debuggable
    * flag set in its manifest, the server returned by this method will
     * be a dummy object that does not doanything. This allows you to use
     * the same code in debug and releaseversions of your application.
     *
     * @param context A Context used to check whether the applicationis
    
*                debuggable, this can be theapplication context
     */
   
public static ViewServer get(Context context) {
       
ApplicationInfo info =context.getApplicationInfo();
        if ( BUILD_TYPE_USER .equals(Build. TYPE ) &&
               
(info. flags & ApplicationInfo. FLAG_DEBUGGABLE ) != 0 ) {
           
if ( sServer == null ) {
               
sServer = new ViewServer(ViewServer. VIEW_SERVER_DEFAULT_PORT );
           
}

            if (! sServer .isRunning()) {
               
try {
                   
sServer .start();
               
} catch (IOException e) {
                   
Log. d( LOG_TAG , "Error:" , e);
               
}
            }
        } else {
           
sServer = new NoopViewServer();
       
}

        return sServer ;
   
}

    private ViewServer() {
       
mPort = - 1 ;
   
}

    /**
    
* Creates a new ViewServerassociated with the specified window manager on the
     * specified local port. The serveris not started by default.
     *
     * @param port The port for the server to listen to.
    
* @see #start()
     */
   
private ViewServer( int port) {
       
mPort = port;
   
}

    /**
    
* Starts the server.
     *
     * @return True if the serverwas successfully created, or false if it already exists.
     * @throws java.io.IOExceptionIf the server cannot be created.
     * @see #stop()
     * @see #isRunning()
     */
   
public boolean start() throws IOException {
       
if ( mThread != null ) {
     
       return false ;
       
}

        mThread = new Thread( this , "LocalView Server [port=" + mPort + "]" );
       
mThreadPool = Executors.newFixedThreadPool( VIEW_SERVER_MAX_CONNECTIONS );
       
mThread .start();

       
return true ;
   
}

    /**
   
 * Stops the server.
     *
     * @return True if the serverwas stopped, false if an error occurred or if the
     * server wasn't started.
     * @see #start()
     * @see #isRunning()
     */
   
public boolean stop() {
       
if ( mThread != null ) {
 
           mThread .interrupt();
           
if ( mThreadPool != null ) {
               
try {
                   
mThreadPool .shutdownNow();
               
} catch (SecurityException e) {
                   
Log. w( LOG_TAG , "Couldnot stop all view server threads" );
               
}
            }

            mThreadPool = null ;
           
mThread = null ;

           
try {
               
mServer .close();
               
mServer = null ;
               
return true ;
           
} catch (IOException e) {
 
              Log. w( LOG_TAG , "Couldnot close the view server" );
           
}
        }

        mWindowsLock .writeLock().lock();
       
try {
           
mWindows .clear();
       
} finally {
           
mWindowsLock .writeLock().unlock();
       
}

         mFocusLock .writeLock().lock();
       
try {
           
mFocusedWindow = null ;
       
} finally {
           
mFocusLock .writeLock().unlock();
       
}

        return false ;
   
}

    /**
    
* Indicates whether the server iscurrently running.
     *
     * @return True if the serveris running, false otherwise.
     * @see #start()
     * @see #stop()
     */
   
public boolean isRunning() {
       
return mThread != null && mThread .isAlive();
   
}

    /**
    
* Invoke this method to register anew view hierarchy.
     *
     * @param activity The activity whose view hierarchy/window toregister
    
* @see #addWindow(android.view.View,String)
     * @see #removeWindow(android.app.Activity)
     */
   
public void addWindow(Activity activity) {
       
String name =activity.getTitle().toString();
        if (TextUtils.isEmpty(name)){
           
name =activity.getClass().getCanonicalName() +
                    "/0x" + System.identityHashCode(activity);
       
} else {
           
name += "(" + activity.getClass().getCanonicalName() + ")" ;
       
}
       addWindow(activity.getWindow().getDecorView(), name);
    }

    /**
    
* Invoke this method to unregister aview hierarchy.
     *
     * @param activity The activity whose view hierarchy/window tounregister
    
* @see #addWindow(android.app.Activity)
     * @see #removeWindow(android.view.View)
     */
   
public void removeWindow(Activity activity) {
       
removeWindow(activity.getWindow().getDecorView());
    }

    /**
    
* Invoke this method to register anew view hierarchy.
     *
     * @param view A view that belongs to the view hierarchy/windowto register
    
* @name name The name of theview hierarchy/window to register
     * @see #removeWindow(android.view.View)
     */
   
public void addWindow(View view, String name) {
       
mWindowsLock .writeLock().lock();
       
try {
           
mWindows .put(view.getRootView(), name);
       
} finally {
           
mWindowsLock .writeLock().unlock();
       
}
        fireWindowsChangedEvent();
    }


    /**
    
* Invoke this method to unregister aview hierarchy.
     *
     * @param view A view that belongs to the view hierarchy/windowto unregister
    
* @see #addWindow(android.view.View,String)
     */
   
public void removeWindow(View view) {
       
mWindowsLock .writeLock().lock();
       
try {
           
mWindows .remove(view.getRootView());
       
} finally {
           
mWindowsLock .writeLock().unlock();
       
}
        fireWindowsChangedEvent();
    }

    /**
    
* Invoke this method to change thecurrently focused window.
     *
     * @param activity The activity whose view hierarchy/windowhasfocus,
    
*                 or null to remove focus
     */
   
public void setFocusedWindow(Activity activity) {
       
setFocusedWindow(activity.getWindow().getDecorView());
    }


    /**
    
* Invoke this method to change thecurrently focused window.
     *
     * @param view A view that belongs to the view hierarchy/windowthat has focus,
    
*            or null to remove focus
     */
   
public void setFocusedWindow(View view) {
       
mFocusLock .writeLock().lock();
       
try {
           
mFocusedWindow = view == null ? null : view.getRootView();
       
} finally {
           
mFocusLock .writeLock().unlock();
       
}
        fireFocusChangedEvent();
    }

    /**
    
* Main server loop.
     */
   
public void run() {
       
try {
           
InetAddress address =InetAddress. getLocalHost();
            mServer = new ServerSocket( mPort , VIEW_SERVER_MAX_CONNECTIONS , address);
       
} catch (Exception e) {
           
Log. w( LOG_TAG , "StartingServerSocket error: " ,e);
       
}

        while ( mServer != null && Thread.currentThread() == mThread ) {
           
// Any uncaught exception will crash the systemprocess
           
try {
               
Socket client = mServer .accept();
               
if ( mThreadPool != null ) {
                   
mThreadPool .submit( new ViewServerWorker(client));
               
} else {
                   
try {
                       
client.close();
                    } catch (IOException e) {
                       
e.printStackTrace();
                    }
                }
            } catch (Exception e) {
               
Log. w( LOG_TAG , "Connectionerror: " ,e);
           
}
        }
    }

    private static boolean writeValue(Socket client, String value) {
       
boolean result;
       
BufferedWriter out = null ;
       
try {
           
OutputStream clientStream =client.getOutputStream();
            out = new BufferedWriter( new OutputStreamWriter(clientStream), 8 * 1024 );
           
out.write(value);
            out.write( "\n" );
           
out.flush();
            result = true ;
       
} catch (Exception e) {
           
result = false ;
  
     } finally {
           
if (out!= null ) {
               
try {
                   
out.close();
                } catch (IOException e) {
                   
result = false ;
               
}
            }
        }
        return result;
   
}

     privatevoid fireWindowsChangedEvent(){
       
for (WindowListener listener : mListeners ) {
           
listener.windowsChanged();
        }
    }

    private void fireFocusChangedEvent() {
       
for (WindowListener listener : mListeners ) {
        
   listener.focusChanged();
        }
    }

    private void addWindowListener(WindowListener listener) {
       
if (! mListeners .contains(listener)) {
           
mListeners .add(listener);
       
}
    }

    private void removeWindowListener(WindowListener listener) {
       
mListeners .remove(listener);
   
}

    private interface WindowListener {
       
void windowsChanged();

       
void focusChanged();
   
}

    private class ViewServerWorker implements Runnable, WindowListener {
       
private Socket mClient ;
       
private boolean mNeedWindowListUpdate ;
       
private boolean mNeedFocusedWindowUpdate ;

       
private final Object[] mLock = new Object[ 0 ];

       
public ViewServerWorker(Socket client) {
           
mClient = client;
      
      mNeedWindowListUpdate = false ;
           
mNeedFocusedWindowUpdate = false ;
       
}

        public void run() {
           
BufferedReader in = null ;
           
try {
               
in = new BufferedReader( new InputStreamReader( mClient .getInputStream()), 1024 );

               
final String request = in.readLine();

               
Log. i( "Command" , "===>" + request);

               
String command;
                String parameters;

                int index = request.indexOf( ' ' );
           
     if (index== - 1 ) {
                   
command = request;
                    parameters = "" ;
               
} else {
                   
command =request.substring( 0 , index);
                   
parameters =request.substring(index + 1 );
         
      }

                boolean result;
               
if ( COMMAND_PROTOCOL_VERSION .equalsIgnoreCase(command)) {
                   
result = writeValue( mClient , VALUE_PROTOCOL_VERSION );
               
} else if ( COMMAND_SERVER_VERSION .equalsIgnoreCase(command)) {
                   
result = writeValue( mClient , VALUE_SERVER_VERSION );
               
} else if ( COMMAND_WINDOW_MANAGER_LIST .equalsIgnoreCase(command)) {
                   
result = listWindows( mClient );
               
} else if ( COMMAND_WINDOW_MANAGER_GET_FOCUS .equalsIgnoreCase(command)) {
                   
result =getFocusedWindow( mClient );
               
} else if ( COMMAND_WINDOW_MANAGER_AUTOLIST .equalsIgnoreCase(command)) {
                   
result =windowManagerAutolistLoop();
                } else {
                   
result =windowCommand( mClient , command, parameters);
               
}

                if (!result){
                   
Log. w( LOG_TAG , "Anerror occurred with the command: " + command);
    
           }
            } catch (IOException e) {
               
Log. w( LOG_TAG , "Connectionerror: " ,e);
           
} finally {
               
if (in!= null ) {
                   
try {
                       
in.close();

                    } catch (IOException e) {
                       
e.printStackTrace();
                    }
                }
                if ( mClient != null ) {
                   
try {
                       
mClient .close();
                   
} catch (IOException e) {
                       
e.printStackTrace();
                    }
                }
            }
        }

        private boolean windowCommand(Socket client, String command,String parameters) {
           
boolean success = true ;
           
BufferedWriter out = null ;

           
try {
               
// Find the hash code of the window
               
int index = parameters.indexOf( ' ' );
               
if (index== - 1 ) {
                   
index =parameters.length();
                }
                 final String code = parameters.substring( 0 ,index);
               
int hashCode = ( int )Long.parseLong(code, 16 );

               
// Extract the command's parameter after thewindow description
               
if (index< parameters.length()) {
   
                parameters =parameters.substring(index + 1 );
               
} else {
                   
parameters = "" ;
               
}
                final View window = findWindow(hashCode);
               
if (window== null ) {
                 
   returnfalse ;
               
}

                // call stuff
               
final Method dispatch = ViewDebug. class .getDeclaredMethod( "dispatchCommand" ,
                       
View. class , String. class , String. class , OutputStream. class );
            
   dispatch.setAccessible( true );
               
dispatch.invoke( null , window, command, parameters,
                       
new UncloseableOutputStream(client.getOutputStream()));

               
if (!client.isOutputShutdown()){
                   
out = new BufferedWriter( new OutputStreamWriter(client.getOutputStream()));
                   
out.write( "DONE\n" );
                   
out.flush();
                }

            } catch (Exception e) {
               
Log. w( LOG_TAG , "Couldnot send command " +command +
                       
" with parameters " + parameters, e);
               
success = false ;
           
} finally {
               
if (out!= null ) {
                   
try {
                       
out.close();
                    } catch (IOException e) {
                       
success = false ;
                   
}
                }
            }

            return success;
       
}

        private View findWindow( int hashCode) {
           
if (hashCode== - 1 ) {
               
View window = null ;
               
mWindowsLock .readLock().lock();
               
try {
                   
window = mFocusedWindow ;
               
} finally {
                   
mWindowsLock .readLock().unlock();
               
}
                return window;
           
}


            mWindowsLock .readLock().lock();
           
try {
               
for (Map.Entry entry : mWindows .entrySet()) {
                   
if (System.identityHashCode(entry.getKey())== hashCode) {
              
          return entry.getKey();
                   
}
                }
            } finally {
               
mWindowsLock .readLock().unlock();
           
}

            return null ;
       
}

        private boolean listWindows(Socket client) {
     
       boolean result = true ;
           
BufferedWriter out = null ;

           
try {
               
mWindowsLock .readLock().lock();

               
OutputStream clientStream= client.getOutputStream();
                out = new BufferedWriter( new OutputStreamWriter(clientStream), 8 * 1024 );

               
for (Map.Entry entry : mWindows .entrySet()) {
                   
out.write(Integer. toHexString(System. identityHashCode(entry.getKey())));
                    out.write( ' ' );
         
          out.append(entry.getValue());
                    out.write( '\n' );
               
}

                out.write( "DONE.\n" );
               
out.flush();
            } catch (Exception e) {
               
result = false ;
           
} finally {
 
               mWindowsLock .readLock().unlock();

               
if (out!= null ) {
                   
try {
                       
out.close();
                    } catch (IOException e) {
                       
result = false ;
                   
}
                }
            }

            return result;
       
}

        private boolean getFocusedWindow(Socket client) {
           
boolean result = true ;
           
String focusName = null ;

           
BufferedWriter out = null ;
           
try {
               
OutputStream clientStream= client.getOutputStream();
                out = new BufferedWriter( new OutputStreamWriter(clientStream), 8 * 1024 );

               
View focusedWindow = null ;

               
mFocusLock .readLock().lock();
 
               try {
                   
focusedWindow = mFocusedWindow ;
               
} finally {
                   
mFocusLock .readLock().unlock();
               
}

                if (focusedWindow!= null ) {
                   
mWindowsLock .readLock().lock();
                   
try {
                       
focusName = mWindows .get( mFocusedWindow );
                   
} finally {
                       
mWindowsLock .readLock().unlock();
                   
}

                    out.write(Integer. toHexString(System. identityHashCode(focusedWindow)));
                    out.write( ' ' );
                   
out.append(focusName);
                }
                out.write( '\n' );
               
out.flush();
            } catch (Exception e) {
       
        result = false ;
           
} finally {
               
if (out!= null ) {
                   
try {
                       
out.close();
                    } catch (IOException e) {
                       
result = false ;
                   
}
                }
            }

            return result;
       
}

        public void windowsChanged() {
           
synchronized ( mLock ){
               
mNeedWindowListUpdate = true ;
               
mLock .notifyAll();
           
}
        }

         publicvoid focusChanged() {
           
synchronized ( mLock ){
               
mNeedFocusedWindowUpdate = true ;
               
mLock .notifyAll();
           
}
        }

        private boolean windowManagerAutolistLoop() {
           
addWindowListener( this );
           
BufferedWriter out = null ;
           
try {
               
out = new BufferedWriter( new OutputStreamWriter( mClient .getOutputStream()));
               
while (!Thread.interrupted()) {
                   
boolean needWindowListUpdate = false ;
                   
boolean needFocusedWindowUpdate = false ;
                   
synchronized ( mLock ){
                       
while (! mNeedWindowListUpdate && ! mNeedFocusedWindowUpdate ) {
                           
mLock .wait();
              
         }
                        if ( mNeedWindowListUpdate ) {
                           
mNeedWindowListUpdate = false ;
                           
needWindowListUpdate = true ;
                       
}
                        if ( mNeedFocusedWindowUpdate ) {
                           
mNeedFocusedWindowUpdate = false ;
                           
needFocusedWindowUpdate = true ;
                       
}
                    }
                    if (needWindowListUpdate){
                       
out.write( "LIST UPDATE\n" );
                       
out.flush();
                    }
                    if (needFocusedWindowUpdate){
                       
out.write( "FOCUS UPDATE\n" );
                       
out.flush();
                    }
                }
            } catch (Exception e) {
               
Log. w( LOG_TAG , "Connectionerror: " ,e);
           
} finally {
               
if (out!= null ) {
                   
try {
                       
out.close();
                    } catch (IOException e) {
                       
// Ignore
                   
}
               
}
                removeWindowListener( this );
           
}
            return true ;
       
}
    }

    private static class UncloseableOutputStream extends OutputStream {
 
       private final OutputStream mStream ;

       
UncloseableOutputStream(OutputStream stream) {
            mStream = stream;
       
}

        public void close() throws IOException {
           
// Don't close the stream
       
}

       
public boolean equals(Object o) {
           
return mStream .equals(o);
       
}

        public void flush() throws IOException {
           
mStream .flush();
       
}

        public int hashCode() {
           
return mStream .hashCode();
       
}

        public String toString() {
           
return mStream .toString();
       
}

        public void write( byte [] buffer, int offset, int count)
               
throws IOException {
           
mStream .write(buffer, offset, count);
       
}

        public void write( byte [] buffer) throws IOException {
           
mStream .write(buffer);
       
}

        public void write( int oneByte) throws IOException {
           
mStream .write(oneByte);
       
}
    }

    /**
    
* 一个空的ViewServer
    
*/
   
private static class NoopViewServer extends ViewServer {
       
private NoopViewServer() {
       
}

        @Override
       
public boolean start() throws IOException {
           
return false ;
       
}

        @Override
       
public boolean stop() {
        
    returnfalse ;
       
}

        @Override
       
public boolean isRunning() {
           
return false ;
       
}

        @Override
       
public void addWindow(Activity activity) {
       
}

        @Override
       
public void removeWindow(Activity activity) {
       
}

        @Override
       
public void addWindow(View view, String name) {
       
}

        @Override
       
public void removeWindow(View view) {
       
}

        @Override
       
public void setFocusedWindow(Activity activity) {
       
}

        @Override
       
public void setFocusedWindow(View view) {
       
}

        @Override
       
public void run() {
       
}
    }

}

参考:http://blog.csdn.net/kdsde/article/details/52984444


更多相关文章

  1. Android 虚化图片的方法
  2. android 显示Gift图片
  3. [置顶] 我的Android进阶之旅------>Android电话窃听实例
  4. android imageview图片显示出来
  5. 2014.01.07 ——— android开发实例之QuickActionBar
  6. Android okHttp上传图片
  7. Mono for Android 显示远程图片
  8. Android 实现仿Window7图片预览窗格效果
  9. Android图片浏览之源码

随机推荐

  1. Android Activity和Intent机制
  2. (2019年10月更新) Android 最全的底部导
  3. Android炫酷的3D球型标签云开源库 3dTagC
  4. Android(安卓)Switch控件介绍
  5. 安卓 打开app进入第一个指定的Activity
  6. Android_百度地图BaiduMap_LocationClien
  7. 韩老师安卓笔记
  8. Android 锁屏生命周期问题
  9. 今天开始写android的照片浏览器(一)至返回
  10. 整理 酷炫 Android(安卓)开源UI框架 动画