Android技术分享



1. 免费在线工具


2. 免费第三方服务

1. 免费在线工具

1.1 在线演示



1. 方便、简单
2.  默认支持部分代码高亮
    public static void main(String[] args) {
        System.out.println("Hello World");

        Log.e("TAG", "日志猫");
        
        int i = 110;
        int j = 9;
        System.out.println(i + j);

        Intent intent = new Intent(this, NewActivity.class);
        startActivity(intent);
    }

1.2 开源中国在线工具





1. 丰富
2. 开源

1.3 json校验格式化





1. 功能强大
2. 丰富

1.4 布局id自动解析

偷懒专用
     <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/txv_game_gift_tag" >

        <TextView
            android:id="@+id/txv_game_gift_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:layout_marginBottom="4dp"
            android:gravity="left"
            android:singleLine="true"
            android:textColor="@color/master_gray_medium"
            android:textIsSelectable="false"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/txv_game_gift_remain_label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/txv_game_gift_name"
            android:text="@string/master_label_remain"
            android:textColor="@color/master_gray_medium"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/txv_game_gift_remain"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:paddingLeft="2dp"
            android:paddingRight="2dp"
            android:paddingTop="0dp"
            android:paddingBottom="0dp"
            android:layout_below="@id/txv_game_gift_name"
            android:layout_toRightOf="@id/txv_game_gift_remain_label"
            android:layout_marginLeft="4dp"
            android:textColor="@color/master_gray_dark"
            android:textIsSelectable="false"
            android:textSize="10sp"
            android:background="@drawable/master_bg_orange_dot" />

        <TextView
            android:id="@+id/txv_game_gift_end_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:layout_below="@id/txv_game_gift_name"
            android:layout_toRightOf="@id/txv_game_gift_remain"
            android:textColor="@color/master_gray_medium"
            android:textIsSelectable="false"
            android:textSize="12sp" />
    </RelativeLayout>

1.5 drawable文件生成工具

偷懒专用
 <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <corners android:radius="14dp" />

    <gradient
        android:angle="45"
        android:centerColor="#7995A8"
        android:centerX="35%"
        android:endColor="#000000"
        android:startColor="#E8E8E8"
        android:type="linear" />

    <padding
        android:bottom="0dp"
        android:left="0dp"
        android:right="0dp"
        android:top="0dp" />

    <size
        android:width="270dp"
        android:height="60dp" />

    <stroke
        android:width="3dp"
        android:color="#878787" />
</shape>

1.6 dp值换算工具


1.7 Android资源生成工具


1.8 Android Weekly订阅



1. 邮件订阅即可,每周推送
2. 包含最新技术资讯、设计资源、开源项目及开发工具


示例

1.9 在线测试





云测
 

2. 免费第三方服务

2.1 推送



极光推送
http://www.jpush.cn/


信鸽推送
http://xg.qq.com/

2.2 分享服务





ShareSdk
http://sharesdk.cn/

2.3 图片处理




Aviary
http://www.aviary.com/


Camera360
需要申请合作,目前已暂停开放

2.4 视频处理




Vitamio
http://www.vitamio.org/

2.5 数据统计服务




友盟
http://www.umeng.com/

2.6 表情服务




表情大全
http://www.stickersdk.com/

2.7 App发布服务





酷传
http://www.coolchuan.com/

2.8 apk解析工具




解析资源文件
https://code.google.com/p/android-apktool/


解析代码文件  
https://code.google.com/p/dex2jar/

2.9 sqlite数据库编辑工具



sqlitebrowser
http://sourceforge.net/projects/sqlitebrowser/   

sqliteman
http://sourceforge.net/projects/sqliteman/?source=navbar

最大的优势只是免费



最后



几句话,装个13



站在巨人的肩膀上


代码,尽可能交给工具去完成

人不是机器,我们应该去做更重要的事情




不要重复造轮子



灵活


用他人的东西自然多少会受限于他人
所以在决定使用它的时候,本身的基础框架就要足够灵活

什么时候看哪个工具、框架不爽了,随时可以T掉它


One More Thing...

尼玛,技术分享没有代码,坑爹么!
Android Java-Bean 生成工具
Ruby语言编写

1. 基于Builder模式
2. 支持Parcelable序列化
3. 支持Gson
4. 开源 gist.github.com


    
## 使命行参数格式:
## ARGV[0]  ==>  config文件路径[必须有]
## ARGV[1]  ==>  保存文件路径[必须有]
## ARGV[2]  ==>  包名[必须有]
## 
## 示例:
## ruby ./AndroidBeanGen.rb ./config.txt ./resp com.a.b
## 
## 
## 
## 
## 
## config文件格式:
## Cls:类名1:类注释1
## 属性名1:属性类型1
## Cls:类名2:类注释2
## 属性名2:属性类型2
## 
## 示例:
## Cls:ArticleReqEntity:文章请求实体
## id:int
## Cls:ArticleRespEntity:文章响应实体
## id:int
## title:String
## list:List<FooEntity>
##
##
##
## ps. 目前已知最低兼容ruby1.8.7
## 
## 1.0.1(2014.03.24):增加set方法集
## 1.0.0(2014.03.20):第一版
##
##
##
# 一个类包含:类名,属性列表和内部类指针
class Clazz
	def initialize(cls_name)
		@cls_name = cls_name
		@cls_comment = ""
		@attrs=[]
		@lead_cls_names=nil  #前面有几个前导类名
		@cls_import_advanced = 0		 #是否需要导入额外内容
	end
	def cls_name
		@cls_name
	end
	
	attr_accessor :cls_comment, :attrs, :lead_cls_names, :cls_import_advanced
end

#属性
class Attr
	def initialize(type=nil,name=nil)
		@type,@name=type,name
	end
	attr_accessor :type, :name
end

class Env
	def initialize()
		@clz_list = []     #类的容器
		@cur_clz = nil     #当前类
		@cur_clz_comment = nil     #当前类注释
		@attr = nil		   #当前属性
		@attr_index=0      #当前类的第几个属性
		@clz_index=0	   #当前属于第几个类
	end
	
	attr_accessor :clz_list,:cur_clz,:cur_clz_comment,:attr,:attr_index,:clz_index
end

$env = Env.new

# 转换首字母大写,此处算法为了兼容ruby1.8.7
def getFirstUpcase(str)
	str_first_cap = str[0].capitalize
	str_remainder = str[1..str.size-1]
	str = "#{str_first_cap}#{str_remainder}"
	return str
end

# 转换首字母小写,此处算法为了兼容ruby1.8.7
def getFirstDowncase(str)
	str_first_min = "0#{str}".capitalize[1]
	str_remainder = str[1..str.size-1]
	str = "#{str_first_min}#{str_remainder}"
	return str
end

def print_clz_list              #测试容器数据
	$env.clz_list.each do |clzz|
		lead_cls_names = clzz.lead_cls_names
		print "============"
		lead_cls_names.each do |lead_names|
			print lead_names + "-"
		end
		print "#{clzz.cls_name}============\n"
		
		attrs = clzz.attrs
		attrs.each do |attr|
			puts attr.type + "=" + attr.name
		end
	end
end

def print_cls_import(i)
	template = "package #{ARGV[2]};\n"
	template += "\n"

	template += "import android.os.Parcel;\n"
	template += "import android.os.Parcelable;\n"
	template += "import com.google.gson.annotations.SerializedName;\n"

	if (i == 1)
		template += "import java.util.List;\n"
	end

	template += "\n"

	template

end

def print_cls_head(i)
	clazz = $env.clz_list[i]
	lead_clz_names = clazz.lead_cls_names
	lead_num = lead_clz_names.size
	cls_name = clazz.cls_name
	cls_comment = clazz.cls_comment
	template = "/**\n"
	template += " * #{cls_comment}\n"
	template += " * <p>build by AndroidBeanGen</p>\n"
	template += " * <a href=\"https\://gist.github.com/pcqpcq/93675e3e02d8d44d8da3\">get it here</a>\n"
	template += " */\n"
	template += "public class #{cls_name} implements Parcelable {\n"
	# if(i == 0)
	# 	template += "public class #{cls_name} {\n"
	# else
	# 	template += "\n"
	# 	template += "\t" * lead_num
	# 	template += "public static class #{cls_name} {\n"
	# end
	
	template
	
end

#返回前导类的个数
def get_lead_num(i)
	lead_cls_names = $env.clz_list[i].lead_cls_names
	lead_num = 0
	# if(lead_cls_names == nil)
	# 	lead_num = 0
	# else
	# 	lead_num = lead_cls_names.size
	# end
	
	lead_num
end

def print_cls_end(i)
	lead_num = get_lead_num(i)
	template = "\t" * lead_num + "}\n\n"
	template
end

def print_attrs(i)
	lead_type = "\t" * get_lead_num(i) + "\t"
	attrs = $env.clz_list[i].attrs
	
	template = "\n"
	attrs.each do |attr|
		type = attr.type
		name = attr.name
		template += "#{lead_type}@SerializedName(\"#{name}\")\n" 
		if type == "String"
			template += "#{lead_type}#{type} #{name} = \"\";\n"
		else
			template += "#{lead_type}#{type} #{name};\n"
		end
	end
	
	template
	
end

def get_template(i)
	clazz = $env.clz_list[i]
	lead_type = "\t" * get_lead_num(i) + "\t"
	template = "\n"
	clazz.attrs.each do |attr|
		first_cap_name = getFirstUpcase(attr.name)

		template += "#{lead_type}public #{attr.type} get#{first_cap_name}() {\n"
		template += "#{lead_type}\treturn #{attr.name};\n"
		template += "#{lead_type}}\n\n"
	end
	template
end

def set_template(i)
	clazz = $env.clz_list[i]
	lead_type = "\t" * get_lead_num(i) + "\t"
	template = ""
	clazz.attrs.each do |attr|
		first_cap_name = getFirstUpcase(attr.name)

		template += "#{lead_type}public void set#{first_cap_name}(#{attr.type} #{attr.name}) {\n"
		template += "#{lead_type}\tthis.#{attr.name} = #{attr.name};\n"
		template += "#{lead_type}}\n\n"
	end
	template
end

def parcel_template(i)
	clazz = $env.clz_list[i]
	template = ""

	# 输出describeContents()方法
	template += "\t@Override\n"
	template += "\tpublic int describeContents() {\n"
	template += "\t\treturn 0;\n"
	template += "\t}\n\n"

	# 输出writeToParcel()方法
	template += "\t@Override\n"
	template +=	"\tpublic void writeToParcel(Parcel dest, int flags) {\n"
	clazz.attrs.each do |attr|
		first_type_name = getFirstUpcase(attr.type)

		# 特殊处理List
		if first_type_name.include? "List"
			first_type_name = "List"
		end
		# 特殊处理实体对象
		if first_type_name.include? "Entity"
			first_type_name = "Parcelable"
			template += "\t\tdest.write#{first_type_name}(this.#{attr.name}, flags);\n"
		else 
			template += "\t\tdest.write#{first_type_name}(this.#{attr.name});\n"
		end
	end
	template += "\t}\n\n"

	# 输出CREATOR对象
	template += "\tpublic static final Parcelable.Creator<#{clazz.cls_name}> CREATOR = new Creator<#{clazz.cls_name}>() {\n\n"
	template += "\t\t@Override\n"
	template += "\t\tpublic #{clazz.cls_name}[] newArray(int size) {\n"
	template += "\t\t\treturn new #{clazz.cls_name}[size];\n"
	template += "\t\t}\n\n"
	template += "\t\t@Override\n"
	template += "\t\tpublic #{clazz.cls_name} createFromParcel(Parcel source) {\n"
	template_builder = ""
	clazz.attrs.each do |attr|
		first_cap_name = getFirstUpcase(attr.name)
		first_type_name = getFirstUpcase(attr.type)

		if first_type_name.include? "List"
			listtype_first_index = 1+first_type_name.index('<')
			listtype_name = first_type_name[listtype_first_index..first_type_name.size-2]
			template += "\t\t\tArrayList<#{listtype_name}> #{attr.name} = new ArrayList<#{listtype_name}>();\n"
			template += "\t\t\tsource.readList(#{attr.name}, #{listtype_name}.class.getClassLoader());\n\n"
		elsif first_type_name.include? "Entity"
			template += "\t\t\t#{attr.type} #{attr.name} = source.readParcelable(#{attr.type}.class.getClassLoader());\n"
		else 
			template += "\t\t\t#{attr.type} #{attr.name} = source.read#{first_type_name}();\n"
		end
		template_builder += "\t\t\t\t\t.set#{first_cap_name}(#{attr.name})\n"
	end
	template += "\n\t\t\treturn new Builder()\n"
	template += template_builder
	template += "\t\t\t\t\t.get#{clazz.cls_name}();\n"
	template += "\t\t}\n"
	template += "\t};\n\n"

	template

end

def builder_template(i=0)
	clazz = $env.clz_list[i]
	cls_name = clazz.cls_name

	instance_name = getFirstDowncase(cls_name)

	attrs = clazz.attrs
	
	lead_type = "\t" * get_lead_num(i) + "\t"
	
	template = "#{lead_type}public static class Builder {\n\n"
	
	template += "#{lead_type}\tprivate #{cls_name} #{instance_name} = new #{cls_name}();\n\n"
	attrs.each do |attr|
		first_cap_name = getFirstUpcase(attr.name)

		template += "#{lead_type}\tpublic Builder set#{first_cap_name}(#{attr.type} #{attr.name}) {\n"
		template += "#{lead_type}\t\t#{instance_name}.#{attr.name} = #{attr.name};\n"
		template += "#{lead_type}\t\treturn this;\n"
		template += "#{lead_type}\t}\n\n"
	end
	
	template += "#{lead_type}\tpublic #{cls_name} get#{cls_name}() {\n"
	template += "#{lead_type}\t\treturn #{instance_name};\n"
	template +="#{lead_type}\t}\n"
	
	template += "#{lead_type}}\n\n"
	
	template
	
end

def genBean

	clazz_list=$env.clz_list
	output_path = ARGV[1]
	0.upto(clazz_list.size-1) do |i|
		cur_clz = clazz_list[i]
		output_file = File.new("#{output_path}/#{cur_clz.cls_name}\.java", "w")

		output_file.puts print_cls_import(cur_clz.cls_import_advanced)

		output_file.puts print_cls_head(i)
		output_file.puts print_attrs(i)
		output_file.puts get_template(i)
		output_file.puts set_template(i)
		output_file.puts parcel_template(i)
		output_file.puts builder_template(i)
		
		output_file.puts print_cls_end(0)

		output_file.close
	end
	
end

=begin
$clz_list = []     #类的容器
$cur_clz = nil     #当前类
$attr = nil		  #当前属性
$attr_index=0      #当前类的第几个属性
$clz_index=0		  #当前属于第几个类
=end

File.open("#{ARGV[0]}", "r:UTF-8"){|f|
	f.each_line do |line|
		line = line.gsub("\n","") #去除换行符
		
		if /^Cls/ =~ line  #碰到以Cls开头,表名以下的属性属于该类
			type_cls_names = line.split(":") #将该行分成两部分,第一部分为Cls,第二部分为类名集合,每个类名之间用-相连
			cls_names = type_cls_names[1].split("-")  #获取类名集合

			# 类名之后的内容为类注释,尝试获取类注释,如果有的话
			if type_cls_names.size > 2
				cls_comment = type_cls_names[2]
				$env.cur_clz_comment = cls_comment
			end
			
			cls_name = cls_names[cls_names.size-1] 
			$env.cur_clz = Clazz.new(cls_name)
			
			$env.cur_clz.lead_cls_names = cls_names[0...cls_names.size-1]  #获取前导类名集合
			
			$env.clz_list[$env.clz_index] = $env.cur_clz; 
			$env.clz_index += 1
			
			$env.attr_index = 0            #重置attr_index
		
		else               #将该类的属性,填充在该类中
			if $env.cur_clz == nil
				puts "nil"
			else
				attr_type_name = line.split(":")
				attr_name=attr_type_name[0]
				attr_type=attr_type_name[1]
				$env.attr = Attr.new(attr_type,attr_name)
				$env.cur_clz.attrs[$env.attr_index] = $env.attr
				$env.attr_index += 1
				
				# 如果包含List,则导入List包
				if (attr_type.include? "List")
					$env.cur_clz.cls_import_advanced = 1
				end

				# 如果当前类有注释
				if $env.cur_clz_comment != nil
					$env.cur_clz.cls_comment = $env.cur_clz_comment
				end
				
			end
		end
		
	end
	
=begin
	print_clz_list
	
	puts get_template(0)
	
	puts builder_template
=end
	genBean
}

config

Cls:StatisticsInfoDbEntity:统计信息数据库实体
id:int
pluginId:String
name:String
introduce:String
colorResName:String
iconResName:String
itemResName:String
cardResName:String
isShow:int

 
package master.com.tmiao.android.gamemaster.entity.db;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.gson.annotations.SerializedName;

/**
 * 插件信息数据库实体
 * <p>build by AndroidBeanGen</p>
 * <a href="https://gist.github.com/pcqpcq/93675e3e02d8d44d8da3">get it here</a>
 */
public class PluginInfoDbEntity implements Parcelable {

	@SerializedName("id")
	int id;
	@SerializedName("pluginId")
	String pluginId = "";
	@SerializedName("name")
	String name = "";
	@SerializedName("introduce")
	String introduce = "";
	@SerializedName("colorResName")
	String colorResName = "";
	@SerializedName("iconResName")
	String iconResName = "";
	@SerializedName("itemResName")
	String itemResName = "";
	@SerializedName("cardResName")
	String cardResName = "";
	@SerializedName("isShow")
	int isShow;

	public int getId() {
		return id;
	}

	public String getPluginId() {
		return pluginId;
	}

	public String getName() {
		return name;
	}

	public String getIntroduce() {
		return introduce;
	}

	public String getColorResName() {
		return colorResName;
	}

	public String getIconResName() {
		return iconResName;
	}

	public String getItemResName() {
		return itemResName;
	}

	public String getCardResName() {
		return cardResName;
	}

	public int getIsShow() {
		return isShow;
	}

	public void setId(int id) {
		this.id = id;
	}

	public void setPluginId(String pluginId) {
		this.pluginId = pluginId;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setIntroduce(String introduce) {
		this.introduce = introduce;
	}

	public void setColorResName(String colorResName) {
		this.colorResName = colorResName;
	}

	public void setIconResName(String iconResName) {
		this.iconResName = iconResName;
	}

	public void setItemResName(String itemResName) {
		this.itemResName = itemResName;
	}

	public void setCardResName(String cardResName) {
		this.cardResName = cardResName;
	}

	public void setIsShow(int isShow) {
		this.isShow = isShow;
	}

	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeInt(this.id);
		dest.writeString(this.pluginId);
		dest.writeString(this.name);
		dest.writeString(this.introduce);
		dest.writeString(this.colorResName);
		dest.writeString(this.iconResName);
		dest.writeString(this.itemResName);
		dest.writeString(this.cardResName);
		dest.writeInt(this.isShow);
	}

	public static final Creator<PluginInfoDbEntity> CREATOR = new Creator<PluginInfoDbEntity>() {

		@Override
		public PluginInfoDbEntity[] newArray(int size) {
			return new PluginInfoDbEntity[size];
		}

		@Override
		public PluginInfoDbEntity createFromParcel(Parcel source) {
			int id = source.readInt();
			String pluginId = source.readString();
			String name = source.readString();
			String introduce = source.readString();
			String colorResName = source.readString();
			String iconResName = source.readString();
			String itemResName = source.readString();
			String cardResName = source.readString();
			int isShow = source.readInt();

			return new Builder()
					.setId(id)
					.setPluginId(pluginId)
					.setName(name)
					.setIntroduce(introduce)
					.setColorResName(colorResName)
					.setIconResName(iconResName)
					.setItemResName(itemResName)
					.setCardResName(cardResName)
					.setIsShow(isShow)
					.getPluginInfoDbEntity();
		}
	};

	public static class Builder {

		private PluginInfoDbEntity pluginInfoDbEntity = new PluginInfoDbEntity();

		public Builder setId(int id) {
			pluginInfoDbEntity.id = id;
			return this;
		}

		public Builder setPluginId(String pluginId) {
			pluginInfoDbEntity.pluginId = pluginId;
			return this;
		}

		public Builder setName(String name) {
			pluginInfoDbEntity.name = name;
			return this;
		}

		public Builder setIntroduce(String introduce) {
			pluginInfoDbEntity.introduce = introduce;
			return this;
		}

		public Builder setColorResName(String colorResName) {
			pluginInfoDbEntity.colorResName = colorResName;
			return this;
		}

		public Builder setIconResName(String iconResName) {
			pluginInfoDbEntity.iconResName = iconResName;
			return this;
		}

		public Builder setItemResName(String itemResName) {
			pluginInfoDbEntity.itemResName = itemResName;
			return this;
		}

		public Builder setCardResName(String cardResName) {
			pluginInfoDbEntity.cardResName = cardResName;
			return this;
		}

		public Builder setIsShow(int isShow) {
			pluginInfoDbEntity.isShow = isShow;
			return this;
		}

		public PluginInfoDbEntity getPluginInfoDbEntity() {
			return pluginInfoDbEntity;
		}
	}

}


Android技术分享

By Joker

Android技术分享

  • 1,232