More Related Content Similar to Layout analyzerでのgroovyの利用について Similar to Layout analyzerでのgroovyの利用について (20) More from kimukou_26 Kimukou More from kimukou_26 Kimukou (6) Layout analyzerでのgroovyの利用について6. では解析してみましょう
使っているツールは?
Layoutopt
日本語解説サイト http://goo.gl/QCMij
本家解説サイト http://goo.gl/7cdt7
どんなツール?
レイアウト.xmlの最適度チェックツール
あくまでナビゲーションだけで変更はしないよ
どこでGroovyを使っているの? useスコープ内だと対象
クラスでCategoryAの
XMLの解析Rule(GroovyRule) ルール(処理)が
Use Category(クラスに機能を後付けする機能) 使えるイメージ
use(CategoryA){
対象クラス、 CategoryA
Clousre A() / B()
}
7. Groovyで実際使うとこんなイメージ
class ExcelCategory {
/** ファイルを読み込む */
static void readXls(File self, Closure yield){ Fileクラスに
readXls()
//読込処理
関数が追加された
} イメージ
/** ファイルを編集する */
static void editXls(File self, Closure yield){
//編集処理
}
}
File self
use (ExcelCategory) { の参照
new File('hogehoge.xls').readXls{ excelApp ->
// hogehoge.xlsに対する何かしらの処理 }
}
}
8. どんな構成になっているの?
ANDROID_HOME/tools/
layoutopt.bat
lib/layoutpot.jar
lib/uix.jar(LayoutAnalyzer , LayoutAnalysis )
lib/groovy-all-1.7.0.jar
実際の構造はどんな感じ?
com.android.layoutopt.cli.Main
LayoutAnalyzer analyzer = new LayoutAnalyzer()
LayoutAnalyzer
loadRules
Rule(Interface)
GroovyRule(implements Rule)
9. 処理の流れの抜粋 Layoutopt.jar
com.android.layoutopt.cli.Main
void main(String[] args)
static void analyzeFiles(File[] files)
LayoutAnalyzer analyzer = new LayoutAnalyzer();
static void analyze(LayoutAnalyzer analyzer, File file)
LayoutAnalysis analysis = analyzer.analyze(file);
uix.jar
com.android.layoutopt.uix.LayoutAnalyzer
LayoutAnalyzer()
loadRules()
loadRule
10. GroovyShellを
初期化
void loadRules()
ClassLoader parent = getClass().getClassLoader();
GroovyClassLoader loader = new GroovyClassLoader(parent);
GroovyShell shell = new GroovyShell(loader);
void loadRule(GroovyShell shell, String name, InputStream stream) {
Script script = shell.parse(stream);
this.mRules.add(new GroovyRule(name, script));
}
public void addRule(Rule rule) が
あるので外からRule追加は可能
かと
com.android.layoutopt.uix.rules.GroovyRule
import com.android.layoutopt.uix.LayoutAnalysis;
import com.android.layoutopt.uix.groovy.LayoutAnalysisCategory;
import groovy.lang.*;
import groovy.xml.dom.DOMCategory;
import java.util.*;
import org.codehaus.groovy.runtime.GroovyCategorySupport;
import org.w3c.dom.Node;
11.
public class GroovyRule implements Rule {
private final String mName;
private final Script mScript;
private final Binding mBinding;
private final Closure mClosure;
private final List<Class> mCategories;
public GroovyRule(String name, Script script) { 実際の処理を行う
this.mName = name; Closure
this.mScript = script;
this.mBinding = new Binding();
this.mScript.setBinding(this.mBinding);
Uix.jar
this.mClosure = new Closure(this) { Rules/XX.rule
public Object call() { を読み込んだスクリプトファ
return GroovyRule.this.mScript.run(); イルデータ
}
};
this.mCategories = new ArrayList();
適応する
Collections.addAll(this.mCategories, Categoryクラス
new Class[]{ を配列定義
DOMCategory.class,
LayoutAnalysisCategory.class });
}
12. Closure、Scriptのクラスのソース抜粋<参考
package groovy.lang;
public abstract class Closure extends GroovyObjectSupport implements Cloneable,
Runnable, Serializable {
public Closure(Object owner, Object thisObject) {
this.owner = owner;
this.delegate = owner;
this.thisObject = thisObject;
CachedClosureClass cachedClass =
CachedClosureClass)ReflectionCache.getCachedClass(getClass());
this.parameterTypes = cachedClass.getParameterTypes();
this.maximumNumberOfParameters =
cachedClass.getMaximumNumberOfParameters();
}
package groovy.lang;
public abstract class Script extends GroovyObjectSupport{
private Binding binding;
public abstract Object run();
}
13. com.android.layoutopt.uix.rules.GroovyRule(続)
public class GroovyRule implements Rule {
~略~
public void run(LayoutAnalysis analysis, Node node) {
this.mBinding.setVariable("analysis", analysis);
this.mBinding.setVariable("node", node);
GroovyCategorySupport.use(
this.mCategories, this.mClosure);
}
}
•GroovyCategorySupport.use ってなに?
•実行処理クラスを別のクラスに後付けする(use)方法です
•http://d.hatena.ne.jp/fumokmm/20090117/1232209001
•下記の関数を後付けします
行番号を表示しているのは
com.android.layoutopt.uix.xml.XmlDocumentBuilder
で行っています
15. uix.jarの Rules/ UselessLayout.rule ファイル
// Rule: UselessLayout
//
// Description: Checks whether current node can be removed.
//
// Conditions: com.android.layoutopt.uix.groovy.LayoutA
// - The node has children nalysisCategory
// - The node does not have siblings public static LayoutAnalysis leftShift(
// - The node's parent is not a scroll view (horizontal or vertical)
// - The node does not have a background or its parent does not have a
// background or neither the node and its parent have a background
// - The parent is not a <merge/>
if (!node.isRoot() && !(node['..'].name() in ["ScrollView", "HorizontalScrollView"])
&&
node['..']['*'].size() == 1 && node['*'].size() > 0 &&
((node.'@android:background' ||
node['..'].'@android:background') || (!node.'@android:background' &&
!node['..'].'@android:background'))) {
analysis << "This ${node.name()} layout or its ${node['..'].name()} parent is " +
"${node['..'].'@android:id' ? "possibly useless" : "useless"}"
}
16. com.android.layoutopt.uix.groovy.LayoutAnalysisCategory
public static int getStartLine(Node node)
public static int getEndLine(Node node)
com.android.layoutopt.uix.groovy.LayoutAnalysisCategory
public static class Issue
内部Innerクラスで使っている
からあえて宣言書いていると思われ
com.android.layoutopt.uix.LayoutAnalysis
public int getStartLine() {
return LayoutAnalysisCategory.getStartLine(this.mNode);
}
public int getEndLine() {
return LayoutAnalysisCategory.getEndLine(this.mNode);
}
17. 他のG系の技術を使ったコード
•GString ・・String型のGroovy拡張クラスです
•@fumokmm さん解説サイト
http://d.hatena.ne.jp/fumokmm/20110323/
計算式OK
•Groovyコード上だと
• int num=2
• String aaa=“ほげほげ$num ${num/20}” と書けます
• String bbb=‘まいう’
• シングルで囲むと普通のString型
com.android.layoutopt.uix.groovy.LayoutAnalysisCategory
import groovy.lang.GString;
public static LayoutAnalysis leftShift(
LayoutAnalysis analysis, GString description){
analysis.addIssue(description.toString());
return analysis;
}
18. •DOMCategory ・・ DOM操作を簡単にするCategory定義クラス
• XML読み(英語) http://goo.gl/SPG93
• XML書き(英語) http://goo.gl/nPxqO
•@nobusue さんサンプル
•https://gist.github.com/619066
com.android.layoutopt.uix.groovy.LayoutAnalysisCategory
import groovy.xml.dom.DOMCategory;
public static List<Node> all(Element element) {
NodeList list = DOMCategory.depthFirst(element);
int count = list.getLength();
List nodes = new ArrayList(count - 1);
for (int i = 1; i < count; i++) {
nodes.add(list.item(i));
}
return nodes;
}
20. Groovyを学習するには
@fumokmm さん
Groovy基礎文法最速マスター
http://d.hatena.ne.jp/fumokmm/20100605/1275736594
Java使いをGroovyに引き込むサンプル集
http://d.hatena.ne.jp/fumokmm/20110213/1297616436
@uehaj さん
DevLOVEぐるぐるGroovyで「気楽に使おう
Groovy」
http://d.hatena.ne.jp/uehaj/20110126/1296003293
とここら辺の情報を見てください
21. Groovyってちょっと試してみたいけど、
インストール面倒くさそうだよね~
自分はGroovyConsoleのWebStart版使ってます
>http://d.hatena.ne.jp/bluepapa32/20101006/1286337869
ここをクリック
22. インストールは手軽~
1. ウインドウ閉じた時に記
述保持機能あるよ
2. Grape やAntBuilder(Ant
のDSL)も問題なしに使え
ます
(Grape機能を使うには、
groovy-allの他にivy.jar
が必要ですが、これには
標準で入っています)
23. えーっ。でも普通、
他ライブラリ使ってるんだけど?
mavenにアクセス
@GrabResolver でmavenURL指定
標準のMavenCentralならいらない
@Grabで落としてくるライブラリ、バージョンを指定
Mavenにないライブラリは?
%USERPROFILE%/.groovy/lib にライブラリ
を入れれば自動的に通せます
GroovyConsoleのメニューから通す事も可能
java –cp “./;lib/*” groovy.ui.GroovyMain
XXX.groovy
の形でBAT起動
24. BATイメージ <デモ有
set JAVA_HOME=C:/opt/jdk
::set JAVA_OPTS=-Dgroovy.source.encoding=UTF-8 -Dfile.encoding=UTF-8
%JAVA_HOME%/bin/java %JAVA_OPTS% -cp ".;./lib/*;./libprocess/*"
groovy.ui.GroovyMain processing_test.groovy
::use groovyConsole
::%JAVA_HOME%/bin/java %JAVA_OPTS% -cp ".;./lib/*;./libprocess/*"
groovy.ui.Console processing_test.groovy
pause
25. 具体例(https://gist.github.com/896140 )
<デモは時間があれば
(name= gridgainsystems ,
root=
(group = net. . , module= cron4j , version= )
pattern=
Scheduler s = Scheduler()
s. (pattern, Runnable() {
() {
println
}})
s. ()
{
Thread. ( * * ) //60秒2回待ち
} (InterruptedException e) {}
s. ()
26. そんなに便利なら何で
Androidに使われてないのw
一応こんなのあります<要Linux環境
@uehaj さん解説 Groovy on android by discobot
http://d.hatena.ne.jp/uehaj/20100515/1273934021
CentOS5.5で試して動かなかったのでパッチココに置きました
https://github.com/kimukou/gradlestudy/tree/master/discobot
27. 使用コードイメージ(UTF8保存)
package org.jggug.sample
import android.app.Activity;
import android.os.Bundle
import android.widget.TextView
public class Main extends Activity{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
TextView tv = new TextView(this)
def list = ["Welcome","to", "discobot." , "¥nAnd", "good",
"luck", "with", "Main!",日本語もOK!"]
def str = ""
list.each {
str += it + " "
}
tv.setText(str)
this.setContentView(tv)
}
}
28. でもWinでJavaだけで
書きたい人には厳しいw
Discobot環境cygwinなら動くのかな?<Win
Groovyをシェル扱いに出来ないからmkProject.sh
動かない
dx.batのdex変換処理でgroovy-all.jarのクロージャクラ
ス変換がStackOverFlowが発生してOutOfMemory出るみた
い
でもWinでJavaだけで書きたい人は垣根高いよね
ASEに期待したいよw(現在未サポート
29. だからGradle等で補助(コンパイル)ツー
ルとして使うのが吉?
Gradleってなに?
Groovyで書かれたビルドツールです
XMLでごちゃごちゃ書いていた記述をDSL記述で
<=pom.xml や build.xml のXML地獄からの脱出
Maven、AntBuilder(AntのDSL)が使えます
時間があれば
ATECのTestterを使ったデモ
使った設定はここにあります
Testter
https://sites.google.com/site/androidtestclub/testter
Gradle設定ファイル(use Android Gradle Plugin)
https://github.com/kimukou/gradlestudy/tree/master/testter
30. Gradleファイル記述例
buildscript {
repositories {
mavenRepo(urls: 'http://jvoegele.com/maven2/')
}
dependencies {
classpath 'com.jvoegele.gradle.plugins:android-plugin:0.9.9'
}
}
apply plugin: 'android' 使うpluginをmaven
repositories { から取得する設定
flatDir(dirs: file("$rootDir/libs"))
//mavenCentral() 使うjarと
} バージョンを記載
dependencies {
compile group: 'org.twitter4j', name: 'twitter4j-core', version: '2.1.8-
SNAPSHOT'
}
31. Gradleファイル記述例(続き1)
// プロジェクトのバージョンを設定
version = "x.y.z"
//ソース位置
[compileJava, compileTestJava]*.options.collect {options -> options.encoding
= 'UTF-8'}
sourceSets.main.java.srcDirs += ['src']
ant.echo sourceSets.main.java.srcDirs
// 署名設定
androidPackage {
//keyStore = System.getProperty('user.home')+"/.android/debug.keystore"
keyStore = "${projectDir}/debug.keystore"
keyAlias = 'androiddebugkey'
// パスワードが設定されてなければ、コマンド・プロンプトで入力
を求められる
keyStorePassword = "android"
keyAliasPassword = "android"
}
32. Gradleファイル記述例(続き2)
// プロジェクトのプロパティをリソースのフィルタリング(プロパティ
の解決)に使うヨ
processResources {
expand (project.properties)
}
jar {
from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
// デバッグ・ビルド設定
task configureDebug << {
jar.classifier = "debug"
Apkに同梱する
} jarを指定します
// リリース・ビルド設定 (この記述の場合は
task configureRelease << { 関連全部)
proguard.enabled = true
}
33. 御静聴ありがとうございました
解析に使ったソフト ANDROID_HOME/
ソース位置が解りませんでした><。 Tools/libディレクトリ上で検
従ってjarを直参照 索すると関連jarが見れます
JD
谷本さん解説ページ http://goo.gl/DRWiR
本家サイト http://goo.gl/ux1I