一直想注册一个服务号未遂,于是只能注册为坑爹的个人账号,才发现各种限制,既不能认证(高级接口需要认证后才能用),开发者认证还得交钱,哎,说好的再小的个体也有自己的品牌呢???
最近遇到最大的问题就是没法本地调试,你得看着接口文档把代码写好,部署到后台去,才能进行测试。
其实我机是可以通过外网访问的。
Mac下线刷Android 设备
今天淘到一个二手nexus6p,因为考虑到安全问题,我需要刷回原生Android,我从官方网站上下载了刷机包
下载地址:
https://developer.android.com/preview/download-712.html
注意,以下线刷方法会清空所有数据,请提前备份。
其次要下载platform-tools 才能使用adb命令,因为我装了Android Studio,
sdk中包含 SDK manager 所以不需要额外下载。
如果你不是开发者,建议只需要下载platform-tools 即可 下载地址:
https://developer.android.com/studio/releases/platform-tools.html#tos-header
选择相应版本下载。
解压,切换到platform-tools 目录下:
让设备切换到bootloader模式下:有两种方式,任选其一
- 运行
adb reboot bootloader
- 关机,按「电源键+音量下」开机
手机进入reboot 模式后,其中有一行小字 好像是 the device is locked 或者device is unlocked ,如果是 locked 则
运行
fastboot flashing unlock
否则略过进入下一步,在此过程中,手机会显示一个确认的操作,请留意。
等待解锁之后,在mac上解压下载的压缩包,命令行切换到解压后的目录中,运行
./flash-all
回车,等待刷机成功吧。成功之后会重启手机。进行一些手机初始化设置之后,开启开发者模式,连接上电脑,重新执行
adb reboot bootloader
进入reboot模式,运行
fastboot flashing lock
重新锁定,大功告成。
Let’s enjoy the new Android!
利用python 构建一个APP 模拟测试环境
背景
做app开发的,和后台连调是一个很重要的工作。在我来到这家公司之前,一只以为所有的功能是后台先开发出来然后app才开始开发。但是由于现在app开发和后台开发是两套人马,所以不可避免的需要同时开发甚至同时上线。我们不得不面临的一个问题是后台只给出了接口,客户端并没有可以连调的环境,这样就不得不自己写虚拟数据模拟。让客户端能够按某个流程能够点下去。
SSH&Vi 编辑器快捷键学习
yy 复制一行
p粘贴
y$ 从光标处复制到结尾
$ 光标移动到行尾
a 在光标后面插入
A 在行尾插入
i 在光标前插入
I 在行前插入
u 撤销上一步操作
SSH
远程登录主机 ssh -username ip
后台运行一个终端 screen
查看上次运行的终端 screen -ls
这时会罗列出终端其中有一个终端号类似 1829等
恢复上次运行的终端 screen -r 终端id
详细学习资料在这里
Q :如何vi保存的时候获取sudo权限
A:命令:w !{cmd},让 vim 执行一个外部命令{cmd},然后把当前缓冲区的内容从 stdin 传入。
tee 是一个把 stdin 保存到文件的小工具。
而 %,是vim当中一个只读寄存器的名字,总保存着当前编辑文件的文件路径。
所以执行这个命令,就相当于从vim外部修改了当前编辑的文件,好完工。
Q:如何在终端隐藏电脑主机名
A:vim /etc/bashrc
用#注释PS1=’\h:\W \u\$ ‘ 同时换行新增 PS1=’\W \$’
Spring MVC 中post json数据返回415错误的一种解决办法
我是通过angular js 发送post 请求给服务器,返回415(不支持的媒体类型),这个问题一度导致我的小项目没有进一步开展,本来我可以换一种方式的,但是不知道哪根筋出问题,非得要post 一段json数据给后台解析。国内外网站找了N种办法均没有解.
反转单向链表
嗯,首先,说一件小事,昨天还在犹豫盒子支付还是海泰康,今天盒子支付经理给我回电话了,说他们也同样能达到海泰康给出的薪资。确实挺欣慰的。能力能够得到公司的认可,说明在深圳,真的是凭能力说话。话说昨天的一道笔试题,用c++实现单项链表的反转链表。我已经快3年没有写过c++了,写的一塌糊涂,不是思想不会而是语法几乎忘记了。
想到这个问题,我立马想到的一个思路就是遍历链表,用一个指针指向最尾节点,然后重新遍历,从第一个节点开始,将每一个节点插入最后一个节点末位。
步骤如下:
12345
23451
34521
45321
54321
今天没事实现了下(写了这么久的java,忽然转到写c++很不习惯,呵呵)
#include<iostream>
#include<set>
using
namespace std;
struct node{
int data;
node *next;
};
//找到最后一个节点
node* findlast(node *head){
while(head->next){
head=head->next;
}
return head;
}
//把目标结点插入到最后一个节点后面
void insert(node *aim,node * last){
if(aim==NULL){return;}
if(NULL==last->next){
last->next=aim;
aim->next=NULL;
}else{
node *temp=last->next;
last->next=aim;
aim->next=temp;
}
}
//反转函数
void reverse(node *head){
node *last=findlast(head);
while(head!=last){
node *temp=head->next;
insert(head,last);
head=temp;
}
cout<<head->data;
}
int main(){
node *nd=NULL,*head=NULL;
for(int i=0;i<5;i++)
{
node *temp=(node *)malloc(sizeof(node));
temp->data=i;
temp->next=NULL;
if(NULL!=nd){
nd->next=temp;
nd=temp;
} else{
head=nd=temp;
}
}
reverse(head);
system("pause");
return 0;
}
利用java反射机制实现对象值拷贝
首先需求是这样的 ,我把它简化一下:
User user1=new User();
user1.setUserName("wxn");
User user2=new User();
user2.setUserName("kkkk");
User user3=user2;
接下来的操作我想让user2中的值和user1中的值全部相等。我们知道可以通过 user2=user1.clone()方法去获得一个新的对象,这种方法的详细介绍在这里可以学习。http://www.cnblogs.com/yxnchinahlj/archive/2010/09/20/1831615.html
但是这样clone出来的是一个新的对象,user2就是user1的一个新对象的拷贝,虽然user2中的值可以和user1中的值相等,但是 user3就已经不是user2之前的对象了,我需要user3中的值也跟着改变。
于是最简单的方法就是在User类中增加一个方法
public void copy(User user){
this.setUserName(user.getUserName);
this.setUserId(user.setUserId);
.....
}
如果user中的属性太多怎么办?那写起来太麻烦了,除了方法名get和set有区别之外没什么区别, 于是我想起了之前看过的java反射机制来批量处理,顺便巩固一下java的反射机制,实现代码如下
public void copy(User user) {
//获得User类中所有的方法
Method[] methods = user.getClass().getMethods();
try {
for (int i = 0; i < methods.length; i++) {
String mName = methods[i].getName();
if (mName.startsWith("set")) {
String nName =null;
//若为boolean的属性则没有get方法 只有 isXXX方法
if(boolean.class.equals(methods[i].getParameterTypes()[0]) ){
nName=mName.replace("set", "is");
} else{
nName=mName.replace("set", "get");
}
Method method = user.getClass().getDeclaredMethod(nName,
null);
methods[i].invoke(this, method.invoke(user, null));
}
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
全部代码如下
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
*
* @author ahsiu
*
*/
public class User {
private int userId;
private String userName;
private String password;
private String email;
private String phone;
private int loginState;
private boolean flag;
public int getUserId() {
return userId;
}
public void copy(User user) {
Method[] methods = user.getClass().getMethods();
try {
for (int i = 0; i < methods.length; i++) {
String mName = methods[i].getName();
if (mName.startsWith("set")) {
String nName =null;
//若为boolean的属性则没有get方法 只有 isXXX方法
if(boolean.class.equals(methods[i].getParameterTypes()[0]) ){
nName=mName.replace("set", "is");
} else{
nName=mName.replace("set", "get");
}
Method method = user.getClass().getDeclaredMethod(nName,
null);
methods[i].invoke(this, method.invoke(user, null));
}
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getLoginState() {
return loginState;
}
public void setLoginState(int loginState) {
this.loginState = loginState;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public static void main(String[] args) {
User user1=new User();
user1.setUserName("wxn");
User user2=new User();
user2.setUserName("kkkk");
User user3=user2;
System.out.println(user1.getUserName());
System.out.println(user2.getUserName());
System.out.println(user3.getUserName());
System.out.println("");
user2.copy(user1);
System.out.println(user1.getUserName());
System.out.println(user2.getUserName());
System.out.println(user3.getUserName());
System.out.println("");
user3.setUserName("ahsiu");
System.out.println(user1.getUserName());
System.out.println(user2.getUserName());
System.out.println(user3.getUserName());
}
}
[转]android解决图片加载oom的方法
大家好,今天给大家分享的是解决解析图片的出现oom的问题,我们可以用BitmapFactory这里的各种Decode方法,如果图片很小的话,不会出现oom,但是当图片很大的时候
就要用BitmapFactory.Options这个东东了,Options里主要有两个参数比较重要.
options.inJustDecodeBounds = false/true; //图片压缩比例. options.inSampleSize = ssize;
我们去解析一个图片,如果太大,就会OOM,我们可以设置压缩比例inSampleSize,但是这个压缩比例设置多少就是个问题,所以我们解析图片可以分为俩个步骤,第一步就是获取图片的宽高,这里要设置Options.inJustDecodeBounds=true,这时候decode的bitmap为null,只是把图片的宽高放在Options里,然后第二步就是设置合适的压缩比例inSampleSize,这时候获得合适的Bitmap.这里我画了简单的流程图,如下:
继续阅读“[转]android解决图片加载oom的方法”android 屏幕图标尺寸规范
1. 程序启动图标:
ldpi (120 dpi)
小屏
mdpi (160 dpi)
中屏
hdpi (240 dpi)
大屏
xhdpi (320 dpi)
特大屏
36 x 36 px
48 x 48 px
72 x 72 px
96 x 96 px
ICON圆角半径
iTunes Artwork icon ───────────────────────── 512px (90px)
App icon(iPhone4) ────────────────────────── 114px (20px)
App icon(iPad) ───────────────────────────── 72px (12px)
App icon(iPhone 3G/3GS) ───────────────────── 57px(10px)
Spotlight/Settings icon icon(iPhone4) ───────────── 58px (10px)
Spotlight/Settings icon icon(iPhone 3G/3GS/iPad) ──── 29px (9px)
android中的dialog
在Android开发中,我们经常需要在界面上弹出一些对话框,比如询问用户或者让用户选择。 下面总结了下dialog的一些样式。
1.该效果是当按返回按钮时弹出一个提示,来确保无误操作,采用常见的对话框样式。
创建dialog对话框方法代码如下:
- protected void dialog() {
- AlertDialog.Builder builder = new Builder(Main.this);
- builder.setMessage(“确认退出吗?”);
- builder.setTitle(“提示”);
- builder.setPositiveButton(“确认”, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- Main.this.finish();
- }
- });
- builder.setNegativeButton(“取消”, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- builder.create().show();
- }
在onKeyDown(int keyCode, KeyEvent event)方法中调用此方法
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
- dialog();
- }
- return false;
- }
2.改变了对话框的图表,添加了三个按钮
创建dialog的方法代码如下:
- Dialog dialog = new AlertDialog.Builder(this).setIcon(
- android.R.drawable.btn_star).setTitle(“喜好调查”).setMessage(
- “你喜欢李连杰的电影吗?”).setPositiveButton(“很喜欢”,
- new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub
- Toast.makeText(Main.this, “我很喜欢他的电影。”,
- Toast.LENGTH_LONG).show();
- }
- }).setNegativeButton(“不喜欢”, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub
- Toast.makeText(Main.this, “我不喜欢他的电影。”, Toast.LENGTH_LONG)
- .show();
- }
- }).setNeutralButton(“一般”, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub
- Toast.makeText(Main.this, “谈不上喜欢不喜欢。”, Toast.LENGTH_LONG)
- .show();
- }
- }).create();
- dialog.show();
3.信息内容是一个简单的View类型
创建dialog方法的代码如下:
- new AlertDialog.Builder(this).setTitle(“请输入”).setIcon(
- android.R.drawable.ic_dialog_info).setView(
- new EditText(this)).setPositiveButton(“确定”, null)
- .setNegativeButton(“取消”, null).show();
4.信息内容是一组单选框
创建dialog方法的代码如下:
- new AlertDialog.Builder(this).setTitle(“单选框”).setIcon(
- android.R.drawable.ic_dialog_info).setSingleChoiceItems(
- new String[] { “Item1”, “Item2” }, 0,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- }).setNegativeButton(“取消”, null).show();
5.信息内容是一组多选框
创建dialog方法的代码如下:
- new AlertDialog.Builder(this).setTitle(“复选框”).setMultiChoiceItems(
- new String[] { “Item1”, “Item2” }, null, null)
- .setPositiveButton(“确定”, null)
- .setNegativeButton(“取消”, null).show();
6.信息内容是一组简单列表项
创建dialog的方法代码如下:
- new AlertDialog.Builder(this).setTitle(“列表框”).setItems(
- new String[] { “Item1”, “Item2” }, null).setNegativeButton(
- “确定”, null).show();
7.信息内容是一个自定义的布局
dialog布局文件代码如下:
- <?xml version=”1.0″ encoding=”utf-8″?>
- <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
- android:layout_height=”wrap_content” android:layout_width=”wrap_content”
- android:background=”#ffffffff” android:orientation=”horizontal”
- android:id=”@+id/dialog”>
- <TextView android:layout_height=”wrap_content”
- android:layout_width=”wrap_content”
- android:id=”@+id/tvname” android:text=”姓名:” />
- <EditText android:layout_height=”wrap_content”
- android:layout_width=”wrap_content” android:id=”@+id/etname” android:minWidth=”100dip”/>
- </LinearLayout>
创建dialog方法的代码如下:
- LayoutInflater inflater = getLayoutInflater();
- View layout = inflater.inflate(R.layout.dialog,
- (ViewGroup) findViewById(R.id.dialog));
- new AlertDialog.Builder(this).setTitle(“自定义布局”).setView(layout)
- .setPositiveButton(“确定”, null)
- .setNegativeButton(“取消”, null).show();
好了,以上7种Android dialog对话框的使用方法就介绍到这里了,基本都全了,如果大家在android开发过程中遇到dialog的时候就可以拿出来看看。
