标签: AndroidStudio

AndroidStudio权威教程 AS添加第三方库的6种方式(Jar module so等)

AndroidStudio权威教程 AS添加第三方库的6种方式(Jar module so等)

点击项目设置按钮

这里写图片描述

依次选择 App > Dependencies

这里写图片描述

1. 直接搜索法

依次选择 + > Library dependency

这里写图片描述

这里的搜索一定要是全名的,不然搜不到哦

这里写图片描述

下图所表示的库和Gradle文件是对应的,后面我们会将Gradle

这里写图片描述

点击OK后,我们会看到AS下边中心位置出现了刷新,以及重新Build项目

这里写图片描述

测试

这里写图片描述

这里如果你想问我的背景怎么设置的那么请看这里:[Android Studio 权威教程]Android Studio 三种添加插件的方式,注意先顶帖哦,可以自己设置图片哦

2. libs添加法

这里直接复制你的第三方jar包到如下目录,我们这里以UML为例子,首先点击Android ,切换到Project

这里写图片描述

找到app > libs ,如果没有libs就新建一个;如果是eclipse导出过来的项目那么这个libs目录直接在根目录下,这点切记

这里写图片描述

现在我们点击下图的按钮重新Build一下项目

这里写图片描述

测试

这里写图片描述

3. Module添加法

这在这里新建了一个Module名称为 mylibrary,和新建项目差不多,这里先不多讲,然后我新建了一个UserTest.class做测试,我们在App中调用这个类

这里写图片描述

然后我们开始添加Module,点击项目设置小按钮

这里写图片描述

app >Dependencies > + >3.Module dependency

这里写图片描述

选择Module

这里写图片描述

然后就看到我们添加的Module了,然后点击ok

这里写图片描述

Build项目中,等到Build完毕我们测试

这里写图片描述

测试

这里写图片描述

4. Gradle 直接添加法

找到build.gradle(Module:app),然后找到dependencies,
这里我们可以看到我们刚才添加的库,刚才那个项目设置是和这里是一一对应的。

这里写图片描述

我们这里以github上android 中Star*多的网络请求框架[android-async-http],我们来到它的官网,我们可以看到这样一段描述:

这里写图片描述

再看看上边的那个图,我们是不是可以直接复制下面的内容就可以了

1.<code class="hljs bash">compile 'com.loopj.android:android-async-http:1.4.5'</code>

这里写图片描述

然后我们重新点击Build按钮,然后开始测试
(注意:这里有时候build一两次是不可以的,需要多build几次,原因你懂得)

这里写图片描述

测试

这里写图片描述

5. 添加.so链接库法

如果你的app需要集成百度地图之类的,一定有这样的so动态库,这里是我自己编译的一个简单的so库,我们做测试:

这里写图片描述

然后复制lib下的所有文件,到AS的app > libs下

这里写图片描述

然后找到build.gradle(Module:app) 文件,在android节点下添加如下内容

1.<code class="hljs bash"><code class="language-java hljs ">sourceSets {
2.main {
3.jniLibs.srcDirs =['libs']
4.}
5.}</code></code>

这里写图片描述

然后build一下

这里写图片描述

看到如下说明成功构建了

这里写图片描述

测试,使用jni给TextView赋值

这里写图片描述

这里写图片描述

这里我们就测试成功了,下面我们讲一种更加简单粗暴的方法

6. 添加.so简单粗暴法

直接创建一个jniLibs目录就可以了,然后复制就好了
路径为:app > src > main >jniLibs

这里写图片描述

到这里我们的添加第三方库的教程就结束了,如果有问题请留言,感谢

01.<code class="hljs bash"><code class="language-java hljs "><code class="language-java hljs ">/**
02.* --------------
03.* 欢迎转载   |  转载请注明
04.* --------------
05.* 如果对你有帮助,请点击|顶|
06.* --------------
07.* 请保持谦逊 | 你会走的更远
08.* --------------
09.* @author zsl
10.* @github https://github.com/yy1300326388
11.* @blog http://blog.csdn.net/yy1300326388
12.*/
13.</code></code></code>

AndroidStudio制作登录和注册功能的实现,界面的布局介绍

设计思路

当我们面临制作登录和注册功能的实现时,我们需要先设计登录界面的布局和注册界面的布局,做到有完整的思路时才开始实现其功能效果会更好。

我们需要做个标题栏,登陆界面,实现登陆界面的功能代码块,注册界面,实现测试界面的功能模块即可完成。

标题栏的设计思路
每个APP都基本上有个标题栏,即是显示标题,标题栏的两侧大多数都有一个返回建。那么标题栏即是一个返回键和一个标题栏的制作布局。

为了避免大多数代码的冗杂,我们把这个标题栏的制作布局独立起来,标题的显示我们可以在每块主题模块上,用setText()方法来显示不同的标题。

接下来我们创建main_title_bar.xml布局文件:
具体代码如下:

<?xml version=”1.0″ encoding=”utf-8″?>
<!–这里代码的是创建一个标题栏,左边是返回键–>
<!–我们设置RelativeLayout布局,id = “title_bar”–>
<RelativeLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/title_bar”
android:layout_width=”match_parent”
android:layout_height=”50dp”
android:background=”@android:color/transparent”>
<!–一个是显示返回键,一个是显示标题框–>
<!–通过TextView来显示,id : tv_back , tv_main_title –>
<TextView
android:id=”@+id/tv_back”
android:layout_width=”50dp”
android:layout_height=”50dp”
android:layout_alignParentLeft=”true”
android:background=”@drawable/go_back_selector” />
<TextView
android:id=”@+id/tv_main_title”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerInParent=”true”
android:textColor=”@android:color/white”
android:textSize=”20sp”/>
<!–其中android:background=”@drawable/go_back_selector”为点击回退键时,会变化效果,其实就是一个点击更换个图片而已。–>
<!–我们先用这种老方法,接下来以后的文章才做代码优化效果–>
</RelativeLayout>
补充:
现在标题栏布局做好了,我们需要了解怎么换图片,就是在android:background=”@drawable/go_back_selector”,其实就是在drawable中创建这个go_back_selector.xml文件而已,用到了android:state_pressed=”true”这个属性,当点击时就是变化的图片效果,记住state_pressed就OK。

登录界面布局
创建登录界面,我们需要标题栏显示“登录”,那么就要通过<include>标签。

我们需要设计想好美化登录界面,需要以下图片:登录背景图片login_bg.png,默认的头像图片default_icon,输入用户名的背景图片login_user_name_bg,在用户名前需要一个小标图user_name_icon,同理,输入密码框需要图片有login_psw_bg,psw_icon,按钮需要图片加以美观register_selector,根据需要的图片可自行制作。

登录界面布局模块代码
创建activity_login.xml布局文件,具体代码如下:

<?xml version=”1.0″ encoding=”utf-8″?>
<!–登录界面,用LinearLayout–>
<LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:background=”@drawable/login_bg”
android:orientation=”vertical”>
<!–标题栏–>
<include layout=”@layout/main_title_bar”></include>
<!–显示头像,记得加入id iv_head –>
<ImageView
android:id=”@+id/iv_head”
android:layout_width=”70dp”
android:layout_height=”70dp”
android:layout_marginTop=”25dp”
android:layout_gravity=”center_horizontal”
android:background=”@drawable/default_icon”/>
<!–输入框–>
<EditText
android:id=”@+id/et_user_name”
android:layout_width=”fill_parent”
android:layout_height=”48dp”
android:layout_marginTop=”35dp”
android:layout_marginLeft=”35dp”
android:layout_marginRight=”35dp”
android:layout_gravity=”center_horizontal”
android:background=”@drawable/login_user_name_bg”
android:drawableLeft=”@drawable/user_name_icon”
android:drawablePadding=”10dp”
android:paddingLeft=”8dp”
android:gravity=”center_vertical”
android:hint=”请输入用户名”
android:singleLine=”true”
android:textColor=”#000000″
android:textColorHint=”#a3a3a3″
android:textSize=”14sp”/>
<!–输入框–>
<EditText
android:id=”@+id/et_psw”
android:layout_width=”fill_parent”
android:layout_height=”48dp”
android:layout_gravity=”center_horizontal”
android:layout_marginLeft=”35dp”
android:layout_marginRight=”35dp”
android:background=”@drawable/login_psw_bg”
android:drawableLeft=”@drawable/psw_icon”
android:drawablePadding=”10dp”
android:paddingLeft=”8dp”
android:gravity=”center_vertical”
android:hint=”请输入密码”
android:inputType=”textPassword”
android:singleLine=”true”
android:textColor=”#000000″
android:textColorHint=”#a3a3a3″
android:textSize=”14sp”/>
<!–按钮–>
<Button
android:id=”@+id/btn_login”
android:layout_width=”fill_parent”
android:layout_height=”40dp”
android:layout_marginTop=”15dp”
android:layout_marginLeft=”35dp”
android:layout_marginRight=”35dp”
android:layout_gravity=”center_horizontal”
android:background=”@drawable/register_selector”
android:text=”登 录”
android:textColor=”@android:color/white”
android:textSize=”18sp”/>
<!–显示tv register , find_psw –>
<LinearLayout
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:layout_marginTop=”8dp”
android:layout_marginLeft=”35dp”
android:layout_marginRight=”35dp”
android:gravity=”center_horizontal”
android:orientation=”horizontal”>
<TextView
android:id=”@+id/tv_register”
android:layout_width=”0dp”
android:layout_height=”wrap_content”
android:layout_weight=”1″
android:gravity=”center_horizontal”
android:padding=”8dp”
android:text=”立即注册”
android:textColor=”@android:color/white”
android:textSize=”14sp” />
<!–layout_weight=”1″ layout_width=”0dp”实现均分效果–>
<TextView
android:id=”@+id/tv_find_psw”
android:layout_width=”0dp”
android:layout_height=”wrap_content”
android:layout_weight=”1″
android:gravity=”center_horizontal”
android:padding=”8dp”
android:text=”找回密码?”
android:textColor=”@android:color/white”
android:textSize=”14sp” />
</LinearLayout>
</LinearLayout>
同理注册界面布局设计思路
创建注册界面,我们需要标题栏显示“注册”,那么就要通过<include>标签。那么我做了效果图,提供思路参考:

注册界面思路图
注册布局模块代码
创建activity_register.xml布局文件,具体代码如下:

<?xml version=”1.0″ encoding=”utf-8″?>
<!–注册界面–>
<!–这里的布局放置是: 1 个 ImageView 控件,用于显示用户头像;3 个 EditText 控件,用于输入用户名、密码、再次输入密码;1 个 Button 控件为注册按钮–>
<!–修改 activity_register.xml 为 LinearLayout 布局–>
<LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/activity_register”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:background=”@drawable/register_bg”
android:orientation=”vertical”>
<include layout=”@layout/main_title_bar”></include><!–引入标题栏–>
<ImageView
android:layout_width=”70dp”
android:layout_height=”70dp”
android:layout_gravity=”center_horizontal”
android:layout_marginTop=”25dp”
android:src=”@drawable/default_icon”/>
<!–三个编辑框–>
<EditText
android:id=”@+id/et_user_name”
android:layout_width=”fill_parent”
android:layout_height=”48dp”
android:layout_gravity=”center_horizontal”
android:layout_marginLeft=”35dp”
android:layout_marginRight=”35dp”
android:layout_marginTop=”35dp”
android:background=”@drawable/register_user_name_bg”
android:drawableLeft=”@drawable/user_name_icon”
android:drawablePadding=”10dp”
android:gravity=”center_vertical”
android:hint=”请输入用户名”
android:paddingLeft=”8dp”
android:singleLine=”true”
android:textColor=”#000000″
android:textColorHint=”#a3a3a3″
android:textSize=”14sp”/>
<EditText
android:id=”@+id/et_psw”
android:layout_width=”fill_parent”
android:layout_gravity=”center_horizontal”
android:layout_height=”48dp”
android:layout_marginLeft=”35dp”
android:layout_marginRight=”35dp”
android:background=”@drawable/register_psw_bg”
android:drawableLeft=”@drawable/psw_icon”
android:drawablePadding=”10dp”
android:hint=”请输入密码”
android:inputType=”textPassword”
android:paddingLeft=”8dp”
android:singleLine=”true”
android:textColor=”#000000″
android:textColorHint=”#a3a3a3″
android:textSize=”14sp”/>
<EditText
android:id=”@+id/et_psw_again”
android:layout_width=”fill_parent”
android:layout_height=”48dp”
android:layout_gravity=”center_horizontal”
android:layout_marginLeft=”35dp”
android:layout_marginRight=”35dp”
android:background=”@drawable/register_psw_again_bg”
android:drawableLeft=”@drawable/psw_icon”
android:drawablePadding=”10dp”
android:hint=”请再次输入密码”
android:inputType=”textPassword”
android:paddingLeft=”8dp”
android:singleLine=”true”
android:textColor=”#000000″
android:textColorHint=”#a3a3a3″
android:textSize=”14sp”/>
<Button
android:id=”@+id/btn_register”
android:layout_width=”fill_parent”
android:layout_height=”40dp”
android:layout_gravity=”center_horizontal”
android:layout_marginLeft=”35dp”
android:layout_marginRight=”35dp”
android:layout_marginTop=”15dp”
android:background=”@drawable/register_selector”
android:text=”注 册”
android:textColor=”@android:color/white”
android:textSize=”18sp”/>
</LinearLayout>
MD5算法
MD5 为 Message-Digest Algorithm 5(信息–摘要算法),记住几个要点就可以了。

Message
Digest
MessageDigest
MessageDigest.getInstance( );
由于注册登录涉及密码,我们需要对用户的密码进行 MD5 算法加密,MD5 算法是把任意长度的字符串变成固定长度(通常是128位)的16进制字符串,且此算法不可逆。
具体代码如下:

package cn.edu.gdmec.android.androidstudiodemo.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
//md5 加密算法
public static String md5(String text) {
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance(“md5”);
// 数组 byte[] result -> digest.digest( ); 文本 text.getBytes();
byte[] result = digest.digest(text.getBytes());
//创建StringBuilder对象 然后建议StringBuffer,安全性高
//StringBuilder sb = new StringBuilder();
StringBuffer sb = new StringBuffer();
// result数组,digest.digest ( ); -> text.getBytes();
// for 循环数组byte[] result;
for (byte b : result){
// 0xff 为16进制
int number = b & 0xff;
// number值 转换 字符串 Integer.toHexString( );
String hex = Integer.toHexString(number);
if (hex.length() == 1){
sb.append(“0″+hex);
}else {
sb.append(hex);
}
}
//sb StringBuffer sb = new StringBuffer();对象实例化
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
//发送异常return空字符串
return “”;
}
}
}
实现注册逻辑功能代码
完成注册页面的布局与 MD5 工具类后,进行注册界面的逻辑编写。

当在注册界面点击注册按钮后,需要获取用户名,用户密码和再次确认密码,当两次密码相同时,将用户名和密码(经过 MD5 加密)保存到 SharedPreferences 中,同时当注册成功后,需要将用户名传递到登录界面中。

RegisterActivity.java具体代码如下:

package cn.edu.gdmec.android.androidstudiodemo;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import cn.edu.gdmec.android.androidstudiodemo.utils.MD5Utils;

public class RegisterActivity extends AppCompatActivity {
private TextView tv_main_title;//标题
private TextView tv_back;//返回按钮
private Button btn_register;//注册按钮
//用户名,密码,再次输入的密码的控件
private EditText et_user_name,et_psw,et_psw_again;
//用户名,密码,再次输入的密码的控件的获取值
private String userName,psw,pswAgain;
//标题布局
private RelativeLayout rl_title_bar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置页面布局 ,注册界面
setContentView(R.layout.activity_register);
//设置此界面为竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
init();
}

private void init() {
//从main_title_bar.xml 页面布局中获取对应的UI控件
tv_main_title=findViewById(R.id.tv_main_title);
tv_main_title.setText(“注册”);
tv_back=findViewById(R.id.tv_back);
//布局根元素
rl_title_bar=findViewById(R.id.title_bar);
rl_title_bar.setBackgroundColor(Color.TRANSPARENT);
//从activity_register.xml 页面中获取对应的UI控件
btn_register=findViewById(R.id.btn_register);
et_user_name=findViewById(R.id.et_user_name);
et_psw=findViewById(R.id.et_psw);
et_psw_again=findViewById(R.id.et_psw_again);
tv_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//返回键
RegisterActivity.this.finish();
}
});
//注册按钮
btn_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取输入在相应控件中的字符串
getEditString();
//判断输入框内容
if(TextUtils.isEmpty(userName)){
Toast.makeText(RegisterActivity.this, “请输入用户名”, Toast.LENGTH_SHORT).show();
return;
}else if(TextUtils.isEmpty(psw)){
Toast.makeText(RegisterActivity.this, “请输入密码”, Toast.LENGTH_SHORT).show();
return;
}else if(TextUtils.isEmpty(pswAgain)){
Toast.makeText(RegisterActivity.this, “请再次输入密码”, Toast.LENGTH_SHORT).show();
return;
}else if(!psw.equals(pswAgain)){
Toast.makeText(RegisterActivity.this, “输入两次的密码不一样”, Toast.LENGTH_SHORT).show();
return;
/**
*从SharedPreferences中读取输入的用户名,判断SharedPreferences中是否有此用户名
*/
}else if(isExistUserName(userName)){
Toast.makeText(RegisterActivity.this, “此账户名已经存在”, Toast.LENGTH_SHORT).show();
return;
}else{
Toast.makeText(RegisterActivity.this, “注册成功”, Toast.LENGTH_SHORT).show();
//把账号、密码和账号标识保存到sp里面
/**
* 保存账号和密码到SharedPreferences中
*/
saveRegisterInfo(userName, psw);
//注册成功后把账号传递到LoginActivity.java中
// 返回值到loginActivity显示
Intent data = new Intent();
data.putExtra(“userName”, userName);
setResult(RESULT_OK, data);
//RESULT_OK为Activity系统常量,状态码为-1,
// 表示此页面下的内容操作成功将data返回到上一页面,如果是用back返回过去的则不存在用setResult传递data值
RegisterActivity.this.finish();
}
}
});
}
/**
* 获取控件中的字符串
*/
private void getEditString(){
userName=et_user_name.getText().toString().trim();
psw=et_psw.getText().toString().trim();
pswAgain=et_psw_again.getText().toString().trim();
}
/**
* 从SharedPreferences中读取输入的用户名,判断SharedPreferences中是否有此用户名
*/
private boolean isExistUserName(String userName){
boolean has_userName=false;
//mode_private SharedPreferences sp = getSharedPreferences( );
// “loginInfo”, MODE_PRIVATE
SharedPreferences sp=getSharedPreferences(“loginInfo”, MODE_PRIVATE);
//获取密码
String spPsw=sp.getString(userName, “”);//传入用户名获取密码
//如果密码不为空则确实保存过这个用户名
if(!TextUtils.isEmpty(spPsw)) {
has_userName=true;
}
return has_userName;
}
/**
* 保存账号和密码到SharedPreferences中SharedPreferences
*/
private void saveRegisterInfo(String userName,String psw){
String md5Psw = MD5Utils.md5(psw);//把密码用MD5加密
//loginInfo表示文件名, mode_private SharedPreferences sp = getSharedPreferences( );
SharedPreferences sp=getSharedPreferences(“loginInfo”, MODE_PRIVATE);
//获取编辑器, SharedPreferences.Editor editor -> sp.edit();
SharedPreferences.Editor editor=sp.edit();
//以用户名为key,密码为value保存在SharedPreferences中
//key,value,如键值对,editor.putString(用户名,密码);
editor.putString(userName, md5Psw);
//提交修改 editor.commit();
editor.commit();
}
}
实现登录逻辑功能代码
完成登录界面布局后,来实现登录界面的逻辑代码。

当点击登录按钮时,需判断用户名和密码是否为空。

若为空,则提示请输入用户名或密码,这里的判断事项比较一开始凌乱,需要细细品味;若不为空,则获取用户输入的用户名,由于用的是本地数据,需要根据用户名在 SharedPreferences 中查询是否有对应的密码,若有对应的密码且与用户输入的密码(需通过 MD5 加密)比对一致情况,则登录成功。

LoginActivity.java具体代码如下:

package cn.edu.gdmec.android.androidstudiodemo;

import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import cn.edu.gdmec.android.androidstudiodemo.utils.MD5Utils;

public class LoginActivity extends AppCompatActivity{
private TextView tv_main_title;//标题
private TextView tv_back,tv_register,tv_find_psw;//返回键,显示的注册,找回密码
private Button btn_login;//登录按钮
private String userName,psw,spPsw;//获取的用户名,密码,加密密码
private EditText et_user_name,et_psw;//编辑框
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//设置此界面为竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
init();
}
//获取界面控件
private void init() {
//从main_title_bar中获取的id
tv_main_title=findViewById(R.id.tv_main_title);
tv_main_title.setText(“登录”);
tv_back=findViewById(R.id.tv_back);
//从activity_login.xml中获取的
tv_register=findViewById(R.id.tv_register);
tv_find_psw=findViewById(R.id.tv_find_psw);
btn_login=findViewById(R.id.btn_login);
et_user_name=findViewById(R.id.et_user_name);
et_psw=findViewById(R.id.et_psw);
//返回键的点击事件
tv_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//登录界面销毁
LoginActivity.this.finish();
}
});
//立即注册控件的点击事件
tv_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//为了跳转到注册界面,并实现注册功能
Intent intent=new Intent(LoginActivity.this,RegisterActivity.class);
startActivityForResult(intent, 1);
}
});
//找回密码控件的点击事件
tv_find_psw.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//跳转到找回密码界面(此页面暂未创建)
}
});
//登录按钮的点击事件
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//开始登录,获取用户名和密码 getText().toString().trim();
userName=et_user_name.getText().toString().trim();
psw=et_psw.getText().toString().trim();
//对当前用户输入的密码进行MD5加密再进行比对判断, MD5Utils.md5( ); psw 进行加密判断是否一致
String md5Psw= MD5Utils.md5(psw);
// md5Psw ; spPsw 为 根据从SharedPreferences中用户名读取密码
// 定义方法 readPsw为了读取用户名,得到密码
spPsw=readPsw(userName);
// TextUtils.isEmpty
if(TextUtils.isEmpty(userName)){
Toast.makeText(LoginActivity.this, “请输入用户名”, Toast.LENGTH_SHORT).show();
return;
}else if(TextUtils.isEmpty(psw)){
Toast.makeText(LoginActivity.this, “请输入密码”, Toast.LENGTH_SHORT).show();
return;
// md5Psw.equals(); 判断,输入的密码加密后,是否与保存在SharedPreferences中一致
}else if(md5Psw.equals(spPsw)){
//一致登录成功
Toast.makeText(LoginActivity.this, “登录成功”, Toast.LENGTH_SHORT).show();
//保存登录状态,在界面保存登录的用户名 定义个方法 saveLoginStatus boolean 状态 , userName 用户名;
saveLoginStatus(true, userName);
//登录成功后关闭此页面进入主页
Intent data=new Intent();
//datad.putExtra( ); name , value ;
data.putExtra(“isLogin”,true);
//RESULT_OK为Activity系统常量,状态码为-1
// 表示此页面下的内容操作成功将data返回到上一页面,如果是用back返回过去的则不存在用setResult传递data值
setResult(RESULT_OK,data);
//销毁登录界面
LoginActivity.this.finish();
//跳转到主界面,登录成功的状态传递到 MainActivity 中
startActivity(new Intent(LoginActivity.this, MainActivity.class));
return;
}else if((spPsw!=null&&!TextUtils.isEmpty(spPsw)&&!md5Psw.equals(spPsw))){
Toast.makeText(LoginActivity.this, “输入的用户名和密码不一致”, Toast.LENGTH_SHORT).show();
return;
}else{
Toast.makeText(LoginActivity.this, “此用户名不存在”, Toast.LENGTH_SHORT).show();
}
}
});
}
/**
*从SharedPreferences中根据用户名读取密码
*/
private String readPsw(String userName){
//getSharedPreferences(“loginInfo”,MODE_PRIVATE);
//”loginInfo”,mode_private; MODE_PRIVATE表示可以继续写入
SharedPreferences sp=getSharedPreferences(“loginInfo”, MODE_PRIVATE);
//sp.getString() userName, “”;
return sp.getString(userName , “”);
}
/**
*保存登录状态和登录用户名到SharedPreferences中
*/
private void saveLoginStatus(boolean status,String userName){
//saveLoginStatus(true, userName);
//loginInfo表示文件名 SharedPreferences sp=getSharedPreferences(“loginInfo”, MODE_PRIVATE);
SharedPreferences sp=getSharedPreferences(“loginInfo”, MODE_PRIVATE);
//获取编辑器
SharedPreferences.Editor editor=sp.edit();
//存入boolean类型的登录状态
editor.putBoolean(“isLogin”, status);
//存入登录状态时的用户名
editor.putString(“loginUserName”, userName);
//提交修改
editor.commit();
}
/**
* 注册成功的数据返回至此
* @param requestCode 请求码
* @param resultCode 结果码
* @param data 数据
*/
@Override
//显示数据, onActivityResult
//startActivityForResult(intent, 1); 从注册界面中获取数据
//int requestCode , int resultCode , Intent data
// LoginActivity -> startActivityForResult -> onActivityResult();
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//super.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
if(data!=null){
//是获取注册界面回传过来的用户名
// getExtra().getString(“***”);
String userName=data.getStringExtra(“userName”);
if(!TextUtils.isEmpty(userName)){
//设置用户名到 et_user_name 控件
et_user_name.setText(userName);
//et_user_name控件的setSelection()方法来设置光标位置
et_user_name.setSelection(userName.length());
}
}
}
}
补充
如做了效果,需要在清单文件中实现该类,文件的跳转,可以自己了解一下。主要介绍注册模块,登录模块。里面的注解我写的如果有不全的或者错误点,可以联系讨论。

接下来你看到如上代码有点多,那么我们可以进行代码的优化来减少代码量。

 

总结
本文讲了AndroidStudio制作登录和注册功能的实现,界面的布局介绍,如果您还有更好地理解,欢迎沟通
定位:分享 Android&Java知识点,有兴趣可以继续关注

AndroidStudio按钮Button退出程序

AndroidStudio 3.1.4

%title插图%num%title插图%num

1.创建一个新的项目,项目名称为Button,界面为activity_button.xml

%title插图%num%title插图%num

2.打开activity_button.xml

%title插图%num%title插图%num

3.点击HelloWorld标签,按Delete删除

%title插图%num%title插图%num

4.左侧组件栏选择Common – Button

%title插图%num%title插图%num

5.将Button组件拖到界面上,大概中间的位置

%title插图%num%title插图%num

6.右侧修改属性

%title插图%num%title插图%num

onClick是鼠标点击事件接收函数,后面写代码需要用到

7.界面完成后的样子

%title插图%num%title插图%num

8.双击java\com.包名.button后面不带括号的

%title插图%num%title插图%num

9.代码编辑框下写代码

%title插图%num%title插图%num

10.代码如下

showdialog为鼠标按下事件接收函数,这个子程序是在鼠标按下按钮Button时触发

 1     public void showdialog(View view)
 2     {
 3         //定义一个新的对话框对象
 4         AlertDialog.Builder alertdialogbuilder=new AlertDialog.Builder(this);
 5         //设置对话框提示内容
 6         alertdialogbuilder.setMessage("确定要退出程序吗?");
 7         //定义对话框2个按钮标题及接受事件的函数
 8         alertdialogbuilder.setPositiveButton("确定",click1);
 9         alertdialogbuilder.setNegativeButton("取消",click2);
10         //创建并显示对话框
11         AlertDialog alertdialog1=alertdialogbuilder.create();
12         alertdialog1.show();
13 
14     }

监听上面定义的对话框按钮事件

 1     private DialogInterface.OnClickListener click1=new DialogInterface.OnClickListener()
 2     {
 3         //使用该标记是为了增强程序在编译时候的检查,如果该方法并不是一个覆盖父类的方法,在编译时编译器就会报告错误。
 4         @Override
 5 
 6         public void onClick(DialogInterface arg0,int arg1)
 7         {
 8             //当按钮click1被按下时执行结束进程
 9             android.os.Process.killProcess(android.os.Process.myPid());
10         }
11     };
12 
13     private DialogInterface.OnClickListener click2=new DialogInterface.OnClickListener()
14     {
15         @Override
16         public void onClick(DialogInterface arg0,int arg1)
17         {
18             //当按钮click2被按下时则取消操作
19             arg0.cancel();
20         }
21     };
22 
23 }

11.完成编写后点击右上角的AVD Manager

%title插图%num %title插图%num%title插图%num

12.选择已下载的模拟器

%title插图%num%title插图%num

13.如果没有下载模拟器可以点击下方的Create Virtual Device进行下载

14.点击Actions下的播放按钮进行运行

%title插图%num%title插图%num

15.成功开启后的样子

%title插图%num%title插图%num

16.点击菜单栏Run下的Run ‘app’进行调试

%title插图%num%title插图%num

17.选择刚刚开启的模拟器型号,点击OK

%title插图%num%title插图%num

18.程序会进行编译,如果没有错误在模拟器中会正常显示

%title插图%num%title插图%num

19.点击调试中软件的BUTTON

%title插图%num%title插图%num

20.点击确定,软件正常结束,证明调试成功

%title插图%num%title插图%num

21.可以选择带签名的打包,编程成apk文件啦!Lucky~

使用AndroidStudio编译NDK的方法及错误解决方案

参考资料:
【android ndk】macos环境下Android Studio中利用gradle编译jni模块及配置: http://demo.netfoucs.com/ashqal/article/details/21869151
ANDROID STUDIO, GRADLE AND NDK INTEGRATION: http://ph0b.com/android-studio-gradle-and-ndk-integration/
Gradle Plugin User Guide: http://tools.android.com/tech-docs/new-build-system/user-guide
New Build System: http://tools.android.com/tech-docs/new-build-system

实践证明:
0.4.2只有在gradle1.10版本下创建只包含AndroidLibrary模块的工程时才能正常编译,gradle1.9版本不可以。
0.4.6使用gradle1.10可以。
0.5.0无论是gradle1.10还是gradle1.11版本都可以生成so库。
0.5.5的不能编译NDK,无论是gradle1.10还是gradle1.11版本都不能生成so库,屙血尿脓。

下载AndroidStudio:
AndroidStudio的历史版本下载列表: http://tools.android.com/download/studio/canary

下载NDK:
下载链接: http://developer.android.com/tools/sdk/ndk/index.html,注意NDK一定要r9+版本的,否则编译时会出现如下 错误:
Execution failed for task ‘:hellojni:compileDebugNdk’.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
D:\ndk\ndk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=F:\androidstudio\test\hellojni\build\ndk\debug\Android.mk APP_PLATFORM=android-19 NDK_OUT=F:\androidstudio\test\hellojni\build\ndk\debug\obj NDK_LIBS_OUT=F:\androidstudio\test\hellojni\build\ndk\debug\lib APP_ABI=armeabi,armeabi-v7a
Error Code:
2
Output:
D:/ndk/build/core/setup-app.mk:63: *** Android NDK: Aborting . Stop.

下载gradle:
gradle-1.9-all.zip: http://download.csdn.net/detail/xxhongdev/6834859
gradle-1.10-all.zip: http://download.csdn.net/detail/xinghuacheng/7026815
gradle-1.11-all.zip: http://download.csdn.net/detail/d1387968/7097249

通过“AndroidStudio历史版本下载列表”下载的历史版本通常是绿色的压缩包,可以直接解压缩使用,但是不包含SDK,需要额外下载SDK,由于之前下载了ADT(版本:adt20131030),所以后面直接使用ADT目录下的SDK。通过 http://developer.android.com/sdk/installing/studio.html首页下载的AndroidStudio为安装版本,包含了SDK,可以下载后直接安装,首次使用创建项目会比较慢,可以参考“ AndroidStudio创建项目时一直处于building“project name”gradle project info的解决办法”来解决。

创建项目:
运行AndroidStudio后,创建新项目,新项目会有一个默认的Module,这里项目名称为JNIDemo,Module为app。

%title插图%num

然后通过向导完成项目的创建。

AndroidStudio还是非常慢的,长时间处于这种状态:

%title插图%num

经过漫长的等待后终于完成项目的创建,然后在这个项目下创建一个Module,New Module->Android Library:

%title插图%num

不勾选“Create activity”然后点击“Finish”完成创建,此时项目结构如图:

%title插图%num

app和hellojni均为JNIDemo下的两个Module,这里把hellojni作为生成so库的NDK开发层,把app作为调用so库的APK引用开发层。

在hellojni模块的src/main下创建jni目录,并在jni目录下新建文件main.cpp,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <assert.h>
#include <sys/types.h>
#include <android/log.h>

#define LOG_TAG “Hellojni”
#define LOGE(…) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGI(…) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

//注册native api的类#define JNIREG_CLASS “com/example/test9/app/MainActivity”

extern “C” {
JNIEXPORT void msg(JNIEnv *env, jobject clazz, jstring str);
};

//jstring to char* char* jstringTostring(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = env->FindClass(“java/lang/String”);
jstring strencode = env->NewStringUTF(“utf-8”);
jmethodID mid = env->GetMethodID(clsstring, “getBytes”, “(Ljava/lang/String;)[B”);
jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0);
return rtn;
}

JNIEXPORT void msg(JNIEnv *env, jobject clazz, jstring str)
{
char *pszstr = NULL;

pszstr = jstringTostring(env, str);
LOGI(“%s”, pszstr);
free(pszstr);
}

/**
* Table of methods associated with a single class.
*/static JNINativeMethod gMethods[] = {
{ “msg”, “(Ljava/lang/String;)V”, (void*)msg},
};

/*
* Register native methods for all classes we know about.
*/static int registerNativeMethods(JNIEnv* env)
{
int nError = 0;
jclass clazz = NULL;

clazz = env->FindClass(JNIREG_CLASS);
if (clazz == NULL) {
LOGE(“clazz is null”);
return JNI_FALSE;
}

nError = env->RegisterNatives(clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0]) );
if ( nError < 0 ) {
LOGE(“RegisterNatives error: %d num: %d”,nError, sizeof(gMethods) / sizeof(gMethods[0]) );
return JNI_FALSE;
}

return JNI_TRUE;
}

/*
* Set some test stuff up.
*
* Returns the JNI version on success, -1 on failure.
*/
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;

if(vm->GetEnv((void**) &env,JNI_VERSION_1_6) != JNI_OK){
return -1;
}
assert(env != NULL);

if (!registerNativeMethods(env)) {
LOGE(“registerNativeMethods failed”);
return -1;
}

/* success — return valid version number */
result = JNI_VERSION_1_6;

return result;
}
这里只导出一个msg函数打印传递进来的字符串,仅作测试。再在jni目录下新建一个empty.cpp文件,内容为空,这个是为了解决NDK的bug所作的,以防编译出错。

打开local.properties,设置正确的SDK路径和NDK路径:
sdk.dir=D\:/adt20131030/sdk
ndk.dir=D\:/ndk
打开项目gradle/wrapper目录下的gradle-wrapper.properties文件,修改:
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-all.zip
为:
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
并打开项目根目录下的build.gradle文件,修改:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath ‘com.android.tools.build:gradle:0.7.+’
}
}

allprojects {
repositories {
mavenCentral()
}
}
为(指定使用gradle1.10则修改为0.9.+,指定使用gradle1.11则修改为0.9.2):
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath ‘com.android.tools.build:gradle:0.9.+’
}
}

allprojects {
repositories {
mavenCentral()
}
}
解释:参考 http://tools.android.com/tech-docs/new-build-system知道
0.7.0
Requires Gradle 1.9
Requires Studio 0.4.0

0.9.0
Compatible with Gradle 1.10 and 1.11
Using Gradle 1.11 requires Android Studio 0.5.0
如果配置的是0.7.+则默认使用gradle1.9,如果设置为0.9.+则默认使用gradle1.10。

另外还需要注意的是gradle1.9下没有buildTypes标签,需要将debug、release标签直接放在android标签内,在gradle1.10下debug、release需要放在buildTypes标签内,buildTypes在android内。这里hellojni配置的build.gradle文件内容如下:
assert gradle.gradleVersion >= “1.10”

apply plugin: ‘android-library’

android {
compileSdkVersion 19
buildToolsVersion “19.0.3”

defaultConfig {
minSdkVersion 8
targetSdkVersion 16
versionCode 1
versionName “1.0”
}

buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.txt’
ndk {
moduleName “hellojni”
abiFilters “armeabi”, “armeabi-v7a”, “x86”
}
}

debug {
ndk {
moduleName “hellojni”
//stl “stlport_shared”
ldLibs “log”, “z”, “m”
//cFlags “-Wall -Wextra -I ” + projectDir + “/src/main/jni/include”
abiFilters “armeabi”, “armeabi-v7a”, “x86”
}
}
}

productFlavors {
x86 {
versionCode Integer.parseInt(“6” + defaultConfig.versionCode)
ndk {
abiFilter “x86”
}
}
mips {
versionCode Integer.parseInt(“4” + defaultConfig.versionCode)
ndk {
abiFilter “mips”
}
}
armv7 {
versionCode Integer.parseInt(“2” + defaultConfig.versionCode)
ndk {
abiFilter “armeabi-v7a”
}
}
arm {
versionCode Integer.parseInt(“1” + defaultConfig.versionCode)
ndk {
abiFilters “armeabi”, “armeabi-v7a”
}
}
fat
}
}

dependencies {
compile ‘com.android.support:appcompat-v7:19.+’
compile fileTree(dir: ‘libs’, include: [‘*.jar’])
}
然后选择hellojni项目右键“Make Module hellojni”,等待一段时间后会在项目下生成build-ndk目录,目录下会有一些不同版本的so库文件生成,如图:

%title插图%num

注意这里的Android.mk文件每次编译都会重新由工具自动生成,而非手动编辑的,我觉得这一点设计就比较差劲。例如如果想要使用log输出函数__android_log_print,需要添加“LOCAL_LDLIBS :=  -llog”,则在build.gradle文件中添加如下的配置:
debug {
ndk {
ldLibs “log”
}
}
由gradle根据配置再去生成Android.mk文件,*后再调用ndk进行编译。

右键工程选择Open Module Settings,选择Modules-app,打开Dependencies选项卡点击“+”号,选择Module dependency,在打开的对话框中选择hellojni。

%title插图%num

但是测试发现设置依赖没有效果,如果直接编译app,hellojni并没有编译,仍需要手动编译hellojni。

调用native函数:

app项目中,在MainActivity类中声明native函数:
public native void msg(String str);
并添加静态代码加载hellojni库:
static {
System.loadLibrary(“hellojni”);
}
在MainActivity::onCreate中调用native函数打印一句log:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msg(“MainActivity onCreate”);
}

还需要将hellojni生成的so库文件打包进apk,仍需要配置build.gradle文件,添加:
task copyNativeLibs(type: Copy) {
from fileTree(dir: ‘../hellojni/build/ndk/arm/debug/lib’, include: ‘armeabi/*.so’) into ‘build/lib’
}
tasks.withType(Compile) {
compileTask -> compileTask.dependsOn copyNativeLibs
}
clean.dependsOn ‘cleanCopyNativeLibs’
tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask ->
pkgTask.jniFolders = [new File(buildDir, ‘lib’)]
}
参考:“Android Studio添加so库” http://blog.csdn.net/caesardadi/article/details/18264399
其中copyNativeLibs任务是从相对app的项目路径’../hellojni/build/ndk/arm/debug/lib’下复制所有armeabi子目录的so文件到本项目build目录下的lib目录中,执行效果:

%title插图%num

这样*后打包生成的apk包才会包含有hellojni的so库文件。

测试:

编译运行app,apk安装完毕运行时输出log信息:

后面列出了可能出现的gradle错误以及解决方案,以供参考。

错误:
Execution failed for task ‘:hellojni:compileDebugNdk’.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
D:\ndk\ndk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=F:\androidstudio\test\hellojni\build\ndk\debug\Android.mk APP_PLATFORM=android-19 NDK_OUT=F:\androidstudio\test\hellojni\build\ndk\debug\obj NDK_LIBS_OUT=F:\androidstudio\test\hellojni\build\ndk\debug\lib APP_ABI=armeabi,armeabi-v7a
Error Code:
2
Output:
make.exe: *** No rule to make target `F:\androidstudio\test\hellojni\build\ndk\debug\obj/local/armeabi/objs/jnimain/F_\androidstudio\test\hellojni\src\main\jni’, needed by `F:\androidstudio\test\hellojni\build\ndk\debug\obj/local/armeabi/objs/jnimain/F_\androidstudio\test\hellojni\src\main\jni\hellojni.o’. Stop.
解决方案:
这是NDK在Windows下一个bug,当只编译一个文件时出现,解决方法就是再添加一个空的文件即可。
原文见 http://ph0b.com/android-studio-gradle-and-ndk-integration/:
This may come from a current NDK bug on Windows, when there is only one source file to compile. You only need to add one empty source to make it work again.

错误:
Could not determine the dependencies of task ‘:hellojni:compileArmDebugJava’.
> failed to find Build Tools revision 19.0.3
解决方案:
这个Build Tools是指“Android SDK Build-tools”,打开SDK Manager勾选相应版本(例如这里是19.0.3)安装即可。

%title插图%num

错误:
FAILURE: Build failed with an exception.

* What went wrong:
Task ‘assembleArmDebug’ not found in project ‘:hellojni’. Some candidates are: ‘assembleDebug’.

* Try:
Run gradle tasks to get a list of available tasks. Run with –stacktrace option to get the stack trace. Run with –info or –debug option to get more log output.
解决方案:
在 android { }中添加:
productFlavors{
arm {
}
}
若有类似错误可以参考加入相应的标签:
productFlavors {
x86 {
versionCode Integer.parseInt(“6” + defaultConfig.versionCode)
ndk {
abiFilter “x86”
}
}
mips {
versionCode Integer.parseInt(“4” + defaultConfig.versionCode)
ndk {
abiFilter “mips”
}
}
armv7 {
versionCode Integer.parseInt(“2” + defaultConfig.versionCode)
ndk {
abiFilter “armeabi-v7a”
}
}
arm {
versionCode Integer.parseInt(“1” + defaultConfig.versionCode)
ndk {
abiFilter “armeabi”
//abiFilters “armeabi”, “armeabi-v7a”
}
}
fat
}

错误:
Execution failed for task ‘:hellojni:compileDebugNdk’.
> java.io.IOException: Cannot run program “D:\ndk\ndk-build”: CreateProcess error=193, %1 ??????Ч?? Win32 ??ó
解决方案:
在使用gradle1.9版本时遇到,使用gradle1.10版本来解决。

错误:
A problem occurred evaluating project ‘:app’.
> Could not create plugin of type ‘AppPlugin’.
解决方案:
Don’t use latest Gradle (version 1.10), downgrade to 1.9。参考: http://blog.vyvazil.eu/tag/android-studio/
但是如果我们使用gradle1.9版本的话又会出现 错误:
Execution failed for task ‘:hellojni:compileDebugNdk’.
> java.io.IOException: Cannot run program “D:\ndk\ndk-build”: CreateProcess error=193, %1 ??????Ч?? Win32 ??ó
无论使用哪个版本都有问题,后来仔细查看了下’AppPlugin’这个错误是出现在‘app’模块上的而非‘hellojni’模块上,于是考虑新建工程项目并且只在该工程下建立一个库模块,不再创建app模块,如图:

%title插图%num

这里不勾选“Create custom launcher icon”和“Create activity”,直接finish完成,其他配置参考前述,*后编译后可以生成so库文件:

%title插图%num
错误:
这个错误忘记记录了囧

解决方案:
File-Settings-Gradle-Gradle VM options:-Xmx512m

%title插图%num

如何将AndroidStudio或Idea软件界面语言系统设置成中文

是不是有时选择功能囿于英文操作不便,这不是在锻炼英文水平!这是在给生产力打折扣
在这里插入图片描述
舒适的操作界面能够让我们快速构造自己想要的操作,那么…


方法

  1. Ctrl+Alt+S打开设置
    在这里插入图片描述
  2. 选择Plugins
    在这里插入图片描述
  3. 输入Chinese,然后找到Chinese (Simplified) Language ,点击install进行安装
    在这里插入图片描述
  4. *后重启IDEA或AndroidStudio,搞定!!!

AndroidStudio实用教程:多界面跳转

1.先创建一个项目,项目文件如下:

在这里插入图片描述

2.activity_double_window.xml代码如下


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DoubleWindow">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

 

3.新建一个布局文件

在这里插入图片描述

4.修改好名字以后Finish
在这里插入图片描述

5.新建一个java类文件

在这里插入图片描述

6.修改好名字以后OK

在这里插入图片描述

7.刚创建的java类源码

package com.shawna.doublewindow;

import android.app.Activity;
import android.os.Bundle;

public class two extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout);
    }
}

 

8.在AndroidManifest.xml文件中增加类文件关联

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shawna.doublewindow">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".DoubleWindow">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        //这一句 ↓
        <activity android:name=".two"></activity>
    </application>

</manifest>

 

9.在一开始创建的主页面上放一个按钮,按钮按下事件名称函数为play

在这里插入图片描述

10.DoubleWindow代码如下:

package com.shawna.doublewindow;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class DoubleWindow extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_double_window);
    }

    //按钮点击事件
    public void play(View view){
        //切换页面
        Intent intent = new Intent(DoubleWindow.this,two.class);
        startActivity(intent);
    }
}

 

 

MAC上使用androidstudio如何关联源码

一路cd 进去到你mac的这个目录下   ~/username/Library/Preferences/AndroidStudio2.X/options/jdk.table.xml,然后open it~~

%title插图%num

在sourcePath下面加入<root type=”simple” url=”jar://$USER_HOME$/Library/Android/sdk/sources/android-22/” />就可以了,当然啦我的是22,你们的可能是更高或者更低~~总之找到对应版本的sourcePath加上对应的这句话,就可以啦~~~,

 

添加:

有的AndroidStudio很顽固,就算像上面那样设置了,重启之后还是会刷新到以前的状态,现在有一个究*解决方案!!!

<jdk version=“2”>

        <name value=“Android API 22 Platform (1)” />

        <type value=“Android SDK” />

        <version value=“java version &quot;1.8.0_74&quot;” />

        <homePath value=“$USER_HOME$/Library/Android/sdk” />

        <roots>

            <annotationsPath>

                <root type=“composite”>

                    <root type=“simple” url=“jar://$APPLICATION_HOME_DIR$/plugins/android/lib/androidAnnotations.jar!/” />

                </root>

            </annotationsPath>

            <classPath>

                <root type=“composite”>

                    <root type=“simple” url=“jar://$USER_HOME$/Library/Android/sdk/platforms/android-22/android.jar!/” />

                    <root type=“simple” url=file://$USER_HOME$/Library/Android/sdk/platforms/android-22/data/res />

                </root>

            </classPath>

            <javadocPath>

                <root type=“composite” />

            </javadocPath>

            <sourcePath>

                <root type=“composite”>

                    <root type=“simple” url=file://$USER_HOME$/Library/Android/sdk/sources/android-22 />

                </root>

            </sourcePath>

        </roots>

        <additional jdk=“1.8” sdk=“android-22” />

    </jdk>

对的!!!就像上面一样,复制一个,名字后面加上(1)就可以了…目前还不知道什么原因,但是解决了..

什么是主流的开发安卓APP的方式?

IDE
曾经的主流,Eclipse+Genymotion

1. 安装Genymotion

默认的虚拟机启动及其困难,也较为卡顿,这时候我们需要一个替代的虚拟机Genymotion了

当然前提是你要有个账号。

下载安装过程就不细说了,选择教育|学习|个人使用版本就行了。

安装完毕后,打开,用账户登陆(没有就去注册),下载自己想要的虚拟机版本,设置分辨路和内存。


2. Genymotion和Eclipse链接

至于链接就需要装个插件了,和安装ADTPlugin一样,
01

接着输入插件地址:http://plugins.genymotion.com/eclipse

02

然后等待以下,把下面选项 Group items by category 选项勾弄掉,接着就出现插件包了,选上就Next,同意,无乱什么都选择Yes,等待下载安装直到完成。

下载安装完成重启Eclipse后会发现多了个这个图标
04

点击以下,会弹出警告,让你设置Genymotion和安装目录,设置你刚才安装的Genymotion的目录,接着确定就行了。

剩下的就一样的了,点击上面那个图标打开虚拟机,然后选择启动虚拟机。

在运行项目之前,先设置以下运行配置
05

选择如下
06


现在的主流,AndroidStudio+Genymotion

1. 安装Android Studio

AndroidStudio的下载地址在下面 ↓ (不要怀疑(→_→),下面那个就是是谷歌官网下载地址)

https://dl.google.com/dl/android/studio/install/2.2.0.12/android-studio-bundle-145.3276617-windows.exe

安装过程同样不在多说,一直下一步到完成就行了。

特别注意!
安装路径不要出现任何中文!!!
不要出现任何中文!!!
不要出现任何中文!!!

2. Android Studio和Genymotion链接

Genymotion安装上面已讲,Android Studio链接Genymotino同样是安装插件,很简单,打开设置
07

在Plugins选项中输入genymotion,搜索到后点击旁边的install,因为我安装了所以显示“Uninstall”
08

如果搜不到就点击下面搜索进行安装
09

一直同意,Next,等待安装完毕后重启。

重启后出现下面的图标。
10

点击打开,会弹出错误,说没设置Genymotion目录,和上面一样,到设置里设置。
11

后面就一样的了,点击小图标来选择启动虚拟机,接着运行项目。

windows下使用AndroidStudio编译so

DK 开发或者老的项目都是基于 Android.mk、Application.mk 来构建项目的,但从 AS 2.2 之后便开始采用 CMake 的方式来构建 C/C++ 项目,采用 CMake 相比与之前的 Android.mk、Application.mk 方便简单了许多。

#1. 指定 cmake 的*小版本
cmake_minimum_required(VERSION 3.4.1)

#2. 设置项目名称
project(demo)

#3. 设置编译类型
add_executable(demo test.cpp) # 生成可执行文件
add_library(common STATIC test.cpp) # 生成静态库
add_library(common SHARED test.cpp) # 生成动态库或共享库

#4. 明确指定包含哪些源文件
add_library(demo test.cpp test1.cpp test2.cpp)

#5. 自定义搜索规则并加载文件
file(GLOB SRC_LIST “*.cpp” “protocol/*.cpp”)
add_library(demo ${SRC_LIST}) //加载当前目录下所有的 cpp 文件
## 或者
file(GLOB SRC_LIST “*.cpp”)
file(GLOB SRC_PROTOCOL_LIST “protocol/*.cpp”)
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
## 或者
aux_source_directory(. SRC_LIST)//搜索当前目录下的所有.cpp文件
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

#6. 查找指定库文件
find_library(
log-lib //为 log 定义一个变量名称
log ) //ndk 下的 log 库

#7. 设置包含的目录
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
)

#8. 设置链接库搜索目录
link_directories(
${CMAKE_CURRENT_SOURCE_DIR}/libs
)

#9. 设置 target 需要链接的库
target_link_libraries( # 目标库
demo

# 目标库需要链接的库
# log-lib 是上面 find_library 指定的变量名
${log-lib} )

#10. 指定链接动态库或者静态库
target_link_libraries(demo libtest.a) # 链接libtest.a
target_link_libraries(demo libtest.so) # 链接libtest.so

#11. 根据全路径链接动态静态库
target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libtest.a)
target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libtest.so)

#12. 指定链接多个库
target_link_libraries(demo
${CMAKE_CURRENT_SOURCE_DIR}/libs/libtest.a
test.a
boost_thread
pthread)

常用变量

%title插图%num
构建 C/C++ Android 项目

以静态库构建项目

1.定义 native 接口

%title插图%num
2.编写 cpp

%title插图%num
3.编写 CmakeLists.txt 文件

%title插图%num
4.app/build.gradle cmake 配置

以动态库构建项目

1.代码加载 so 库到手机中

%title插图%num
2.so 库导入在 main/jniLibs 下

%title插图%num

3.CmakeLists.txt 配置

%title插图%num

4.在AS上编译运行,截图省略

AndroidStudio下的APP目录结构介绍

Project Name:工程项目名称
Application Name:当前应用发布以后的名字,例如QQ图标下面的名字是“QQ”,就是Application Name.

Android Studio工程目录

%title插图%num

1、.gradle和.idea
这两个目录下放置的都是Android Studio自动生成的一些文件,我们无须关心,也不要去手动编辑。
2、app
项目中的代码、资源等内容几乎都是放置在这个目录下的,我们后面的开发工作也基本都是在这个目录下进行的,待会儿还会对这个目录单独展开进行讲解。
3、build
这个目录你也不需要过多关心,它主要包含了一些在编译时自动生成的文件。
4、gradle
这个目录下包含了gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。Android Studio默认没有启动gradle wrapper的方式,如果需要打开,可以点击Android Studio导航栏 –> File –> Settings –> Build,Execution,Deployment –> Gradle,进行配置更改。
5、.gitignore
这个文件是用来将指定的目录或文件排除在版本控制之外的。
6、build.gradle
这是项目全局的gradle构建脚本,通常这个文件的内容是不需要修改的。下面回详细分析gradle构建脚本中的具体内容。
7、gradle.properties
这个文件是全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本。
8、gradlew和gradlew.bat
这两个文件是用来在命令行界面中执行gradle命令的,其中gradlew是在Linux或Mac系统中使用的,gradlew.bat是在Windows系统中使用的。
9、HelloWorld.iml
iml文件是所有IntelliJ IDEA项目都会自动生成的一个文件(Android Studio是基于IntelliJ IDEA开发的),用于标识这是一个IntelliJ IDEA项目,我们不需要修改这个文件中的任何内容。
10、local.properties
这个文件用于指定本机中的Android SDK路径,通常内容都是自动生成的,我们并不需要修改。除非你本机中的Android SDK位置发生了变化,那么就将这个文件中的路径改成新的位置即可。
11、settings.gradle
这个文件用于指定项目中所有引入的模块。由于HelloWorld项目中就只有一个app模块,因此该文件中也就只引入了app这一个模块。通常情况下模块的引入都是自动完成的,需要我们手动去修改这个文件的场景可能比较少。

app目录结构

除了app目录之外,大多数的文件和目录都是自动生成的不需要我们进行修改,下面我们详细介绍app目录结构。

%title插图%num

1、build
这个目录和外层的build目录类似,主要也是包含了一些在编译时自动生成的文件,不过它里面的内容会更多更杂,我们不需要过多关系。
2、libs
如果你的项目中使用到了第三方jar包,就需要把这些jar包都放在libs目录下,放在这个目录下的jar包都会被自动添加到构建路径里去。
3、src/AndroidTest
此处是用来编写Android Test测试用例的,可以对项目进行一些自动化测试。
4、src/main/java
毫无疑问,java目录是放置我们所有java代码的地方,展开该目录,你将看到我们刚才创建的HelloWorldActivity文件就在里面。
5、src/main/res
这个目录下的内容就有点多了。简单点说,就是你在项目中使用到的所有图片,布局,字符串等资源都要存放在这个目录下。当然这个目录下还有很多子目录,图片放在drawable目录下,布局放在layout目录下,字符串放在values目录下,所以你不用担心会把整个res目录弄得乱糟糟的。
6、main/AndroidManifest.xml
这是你整个Android项目的配置文件,你在程序中定义的所以四大组件都需要在这个文件里注册,另外还可以在这个文件中给应用程序添加权限声明。
7、test
此处是用来编写Unit Test测试用例的,是对项目进行自动化测试的另一种方式。
8、.gitignore
这个文件用于将app模块内的指定的目录或文件排除在版本控制之外,作用和外层的.gitignore文件类似。
9、app.iml
IntelliJ IDEA项目自动生成的文件,我们不需要关心或修改这个文件中的内容。
10、build.gradle
这是app模块的gradle构建脚本,这个文件中会指定很多项目构建相关的配置。
11、proguard-rules.pro
这个文件用于指定项目代码的混淆规则,当代码开发完成后打成安装包文件,如果不希望代码被别人破解,通常会将代码混淆,从而让破解者难以阅读。

项目中的资源

展开res目录看一下,其实里面的东西还是挺多的,很容易让人看得眼花缭乱,如下图:

%title插图%num

以drawable开头的文件夹都是用来放图片的;
以mipmap开头的文件夹都是用来放应用图标的;
以values开头的文件夹都是用来放字符串、样式、颜色等配置的;
layout文件夹是用来放布局文件的。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速