android开发中自定义dialog的布局样式实例

 更新时间:2016年9月20日 19:57  点击:2389
本文我来分享一下我的自定义dialog的样式的实现方法,其实也非常简单,请看后面我给出的实例。

在网上找了很多关于dialog的自定义样式的问题,还有很多人写得比较复杂,需要改动style什么的,或者是自定义dialog搞得很复杂,我最后还是找到了方法来实现。

下面是我的dialog布局xml文件:

[mw_shl_code=java,true]<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/transparent"
    android:layout_margin="50dp">
   
    <RelativeLayout
        android:id="@+id/rl_dialog_content"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:background="@drawable/alertdialog_bg">
            <TextView
                android:id="@+id/dialog_text"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="现在就打电话给客服:arjinmc"           
                android:layout_marginTop="50dp"     
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                android:maxLines="5"
                android:gravity="center"
                />        
               
            <LinearLayout
                android:id="@+id/ll_buttons"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_alignParentBottom="true"
                android:layout_margin="30dp">
               
               
                <Button
                 android:id="@+id/dialog_cancel"
                 android:text="@string/alert_cancel"
                 android:background="@drawable/btn_long_white"
                 style="@style/dialog_button"
                 android:layout_weight="1"
                 android:textColor="@color/tabs_font"
                 />
                <Button
                 android:id="@+id/dialog_ok"
                 android:text="@string/alert_ok"
                 android:background="@drawable/btn_long_red"
                 style="@style/dialog_button"
                 android:layout_weight="1"
                 android:layout_marginLeft="5dp"/>
               
            </LinearLayout>
    </RelativeLayout>
    <ImageButton
        android:id="@+id/dialog_close"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/alertdialog_close"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="20dp"
       />   
   

</RelativeLayout>
[/mw_shl_code]


在代码中需要这样写就可以了:
[mw_shl_code=java,true]//布局文件转换为view对象
  LayoutInflater inflaterDl = LayoutInflater.from(this);
  RelativeLayout layout = (RelativeLayout)inflaterDl.inflate(R.layout.layout_dialog, null );
 
  //对话框
  final Dialog dialog = new AlertDialog.Builder(SettingActivity.this).create();
  dialog.show();
  dialog.getWindow().setContentView(layout);
 
 
  //取消按钮
  Button btnCancel = (Button) layout.findViewById(R.id.dialog_cancel);
  btnCancel.setOnClickListener(new OnClickListener() {
        
        @Override
        public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "cancel", Toast.LENGTH_SHORT).show();                                
        }
  });
 
 
  //确定按钮
  Button btnOK = (Button) layout.findViewById(R.id.dialog_ok);
  btnOK.setOnClickListener(new OnClickListener() {
        
        @Override
        public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "ok", Toast.LENGTH_SHORT).show();                                
        }
  });
 
 
  //关闭按钮
  ImageButton btnClose = (ImageButton) layout.findViewById(R.id.dialog_close);
  btnClose.setOnClickListener(new OnClickListener() {
        
        @Override
        public void onClick(View v) {
                dialog.dismiss();                                
        }
  });[/mw_shl_code]


非常easy!自己动手吧。



自定义dialog的样式并比较日期

<style name="myDialogTheme" parent="android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item>
</style>


1、布局main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <Button
        android:id="@+id/btn"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:text="按下按钮试试"/>

</LinearLayout>

2、ly_dialogcontent

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="220dp"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="#88E0EEEE">
    <LinearLayout
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:orientation="vertical">
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="@android:color/white"
            android:textSize="20sp"
            android:text="查询"
            android:gravity="center"
            android:layout_gravity="center"
            android:padding="10dp"/>
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:gravity="center">
            <TextView
                
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="开始时间:"/>
            <EditText
                android:id="@+id/beginTime"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:singleLine="true"/>
          </LinearLayout>
          <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:gravity="center">
            <TextView
                
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="开始时间:"/>
            <EditText
                android:id="@+id/endTime"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:singleLine="true"/>
          </LinearLayout>
          <LinearLayout
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:gravity="center">
              <Button
                  android:id="@+id/search"
                  android:layout_height="wrap_content"
                  android:layout_width="wrap_content"
                  android:layout_weight="1.0"
                  android:text="查询"/>
              <Button
                  android:id="@+id/cancel"
                  android:layout_height="wrap_content"
                  android:layout_width="wrap_content"
                  android:layout_weight="1.0"
                  android:text="取消"/>
              
          </LinearLayout>
        
    </LinearLayout>

    

</RelativeLayout>

3、Mainactivity

package com.ct.dialog;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    private Button btnBn;
    private Dialog dlg;
    private LayoutInflater mInflater;
    private Calendar calendar;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btnBn = (Button)findViewById(R.id.btn);
        init();
        btnBn.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                dlg.show();
            }
        });
    }
    
    private void init(){
        calendar = Calendar.getInstance();
        dlg = new Dialog(MainActivity.this, R.style.myDialogTheme);
        mInflater = LayoutInflater.from(MainActivity.this);
        dlg.setCancelable(true);
        dlg.setCanceledOnTouchOutside(true);
        
        View view = mInflater.inflate(R.layout.ly_dialogcontent, null);
        final EditText begin = (EditText)view.findViewById(R.id.beginTime);
        final EditText end = (EditText)view.findViewById(R.id.endTime);
        Button sbtn = (Button)view.findViewById(R.id.search);
        Button clebt = (Button)view.findViewById(R.id.cancel);
        begin.setInputType(InputType.TYPE_NULL);
        end.setInputType(InputType.TYPE_NULL);
        dlg.setContentView(view);
        //取消
        clebt.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                dlg.dismiss();
            }
        });
        
        //查询
        sbtn.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                String beginTime =  begin.getText().toString();
                String endTime = end.getText().toString();
                if (beginTime.equals("")|| endTime.equals("")) {

                    Toast.makeText(MainActivity.this, "都不能为空", Toast.LENGTH_LONG).show();

                }else if(!isLarge(beginTime, endTime)){
                    Toast.makeText(MainActivity.this, "结束时间不能比开始时间小", Toast.LENGTH_LONG).show();
                } else {
                    dlg.dismiss();}
            }
        });
        
        //开始时间
        begin.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                final String second = "00";
                DatePickerDialog dpg = new DatePickerDialog(MainActivity.this,
                        new OnDateSetListener() {
                            
                            @Override
                            public void onDateSet(DatePicker view, int year, int monthOfYear,
                                    int dayOfMonth) {
                                // TODO Auto-generated method stub
                                begin.setText(year+"-"+
                                format(++monthOfYear)+"-"+
                                format(dayOfMonth));
                                
                                TimePickerDialog tpg = new TimePickerDialog(MainActivity.this,
                                        new OnTimeSetListener(){

                                            @Override
                                            public void onTimeSet(
                                                    TimePicker arg0, int hourOfDay,
                                                    int minute) {
                                                // TODO Auto-generated method stub
                                                begin.setText(begin.getText().toString()
                                                        + " "
                                                        + format(hourOfDay)
                                                        + ":"
                                                        + format(minute)
                                                        + ":" + second);
                                            }},calendar.get(Calendar.HOUR_OF_DAY),
                                        calendar.get(Calendar.MINUTE), true);
                                tpg.show();
                            }
                        }, calendar.get(Calendar.YEAR),
                        calendar.get(Calendar.MONTH),
                        calendar.get(Calendar.DAY_OF_MONTH));
                
                dpg.show();
            }
        });
        //结束时间
        end.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                final String second = "00";
                DatePickerDialog dpg = new DatePickerDialog(MainActivity.this,
                        new OnDateSetListener() {
                            
                            @Override
                            public void onDateSet(DatePicker view, int year, int monthOfYear,
                                    int dayOfMonth) {
                                // TODO Auto-generated method stub
                                end.setText(year+"-"+
                                format(++monthOfYear)+"-"+
                                format(dayOfMonth));
                                
                                TimePickerDialog tpg = new TimePickerDialog(MainActivity.this,
                                        new OnTimeSetListener(){

                                            @Override
                                            public void onTimeSet(
                                                    TimePicker arg0, int hourOfDay,
                                                    int minute) {
                                                // TODO Auto-generated method stub
                                                end.setText(begin.getText().toString()
                                                        + " "
                                                        + format(hourOfDay)
                                                        + ":"
                                                        + format(minute)
                                                        + ":" + second);
                                            }},calendar.get(Calendar.HOUR_OF_DAY),
                                        calendar.get(Calendar.MINUTE), true);
                                tpg.show();
                            }
                        }, calendar.get(Calendar.YEAR),
                        calendar.get(Calendar.MONTH),
                        calendar.get(Calendar.DAY_OF_MONTH));
                
                dpg.show();
            }
        });
        
        
    }
    
    /**
     * 比较两个时间的大小
     * @throws ParseException
     *
     * */
    public static boolean isLarge(String beginTime,String endTime) {
        boolean flag = false;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date begin = sdf.parse(beginTime);
            Date edn = sdf.parse(endTime);
            if(edn.getTime() - begin.getTime() >0){
                flag = true;
            }else {
                flag = false;
            }
            
        } catch (ParseException e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return flag;
        
    }
    
    
    /**
     * 在一位数字前加0变成两位数字
     *
     * @param value
     * @return
     */
    private String format(int value) {
        String s = String.valueOf(value);
        if (s.length() == 1) {
            s = "0" + s;
        }
        return s;
    }
}

 (在F:\java\z自定义dialog+点击弹出时间调整那个\MyDialogTheme)

签名这个东西有点像以前手机应用了需要生成一个签名,当时只有指定的几个网站可以生成了,现在的安卓应用相对好做一些,下面一介绍一个安卓应用签名的例子。

1、生成正式版本,并找到unsigned文件的路径,记下来


demo-unsigned.apk

2、用keytool生成签名keystore文件

keytool -genkey -v -keystore <keystoreName>.keystore -alias <Keystore AliasName> -keyalg <Key algorithm> -keysize <Key size> -validity <Key Validity in Days>

  <keystoreName>:要生成的签名文件名,扩展名为 keystore
<Keystore AliasName>:签名的别名,作为唯一性依据
<Key algorithm>:加密方式,譬如RSA
<Key size>:签名长度,可忽略
<Key Validity in Days>:有效期,单位是 天

  输入以上命令后,接下来按提示操作,分别是:
输入密码,
确认密码,
组织单位名称,
组织名称,
市,
省,
国家两字母代码(中国是CN)

  最后,核对以上信息,按Y完成

  输入主密码,这里我不是太了解为什么要分两个,直接回车表示使用相同密码。

3、用jarsigner给未签名的应用签名并生成已签名的应用


jarsigner -verbose -keystore <keystorename> -signedjar <Output Signed APK file> -digestalg SHA1 -sigalg MD5withRSA <Unsigned APK file> <Keystore Alias name>

  <keystorename>:上一步通过keytool生成的签名文件(带扩展名keystore)
<Output Signed APK file>:签名后输出的文件
<Unsigned APK file>:未签名且此刻用于签名的文件
<Keystore Alias name>:签名的别名(不带扩展名keystore)

  然后,按提示输入上一步设置的密码,即可大功告成。


关于keytool和jarsigner显示乱码的问题,解决方法

部分脚本在 MAC OS X 的终端输出不了正常中文,取而代之的是?,即乱码,原因是其编码不正确。本以为UTF-8可以打天下,谁知有人不按常理出牌,比如keytool和jarsigner。。。

解决方法:
打开终端后在菜单-偏好设置-描述文件-高级,下面有文本编码的设置,默认是UTF-8,这里我改为中文(GB 18030),至少keytool和jarsigner返回的中文可以正常显示。

注意:
不同的颜色风格自有一套高级选项,所以修改了文本编码后切换其他的颜色风格不会把该设置带过去

本文我们来分享android开发中怎么样获取手机上所有的可用的外置SD卡的方法,这个功能非常有用,因为一般人的都会外置SD卡。

现在的android手机型号复杂多样,造成了开发过程中使用官方的获取sd卡的方法在部分的手机上并不适用,所以需要进行开发的自己封装,以下就是代码,希望分享出来,大家共同学习

/**
* 获取手机sd卡的工具类
* @author wy
*/
public class SDCardUtils {
/*
* avoid initializations of tool classes
*/
private SDCardUtils() {
// TODO Auto-generated constructor stub
}

/**
* @Title: getExtSDCardPaths
* @Description: to obtain storage paths, the first path is theoretically
* the returned value of
* Environment.getExternalStorageDirectory(), namely the
* primary external storage. It can be the storage of internal
* device, or that of external sdcard. If paths.size() >1,
* basically, the current device contains two type of storage:
* one is the storage of the device itself, one is that of
* external sdcard. Additionally, the paths is directory.
* @return List<String>
* @throws IOException
* 获取手机上所有可用的sd卡路径
* @return
*/
public static ArrayList<String> getExtSDCardPaths() {
ArrayList<String> paths = new ArrayList<String>();
String extFileStatus = Environment.getExternalStorageState();
File extFile = Environment.getExternalStorageDirectory();
if (extFileStatus.equals(Environment.MEDIA_MOUNTED) && extFile.exists()
&& extFile.isDirectory()) {
paths.add(extFile.getAbsolutePath());
}
try {
// obtain executed result of command line code of 'mount', to judge
// whether tfCard exists by the result
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("mount");
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
int mountPathIndex = 1;
while ((line = br.readLine()) != null) {
// format of sdcard file system: vfat/fuse
if ((!line.contains("fat") && !line.contains("fuse") && !line
.contains("storage"))
|| line.contains("secure")
|| line.contains("asec")
|| line.contains("firmware")
|| line.contains("shell")
|| line.contains("obb")
|| line.contains("legacy") || line.contains("data")) {
continue;
}
String[] parts = line.split(" ");
int length = parts.length;
if (mountPathIndex >= length) {
continue;
}
String mountPath = parts[mountPathIndex];
if (!mountPath.contains("/") || mountPath.contains("data")
|| mountPath.contains("Data")) {
continue;
}
File mountRoot = new File(mountPath);
if (!mountRoot.exists() || !mountRoot.isDirectory()) {
continue;
}
boolean equalsToPrimarySD = mountPath.equals(extFile
.getAbsolutePath());
if (equalsToPrimarySD) {
continue;
}
paths.add(mountPath);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return paths;
}

/**
* SD卡剩余空间大小
* @param path 取得SD卡文件路径
* @return 单位MB
*/
public static long getSDFreeSize(String path) {
StatFs sf = new StatFs(path);
// 获取单个数据块的大小(Byte)
long blockSize = sf.getBlockSize();
// 空闲的数据块的数量
long freeBlocks = sf.getAvailableBlocks();
// 返回SD卡空闲大小
return (freeBlocks * blockSize) / 1024 / 1024; //
}

/**
* SD卡总容量
* @param path 取得SD卡文件路径
* @return 单位MB
*/
public static long getSDAllSize(String path) {
StatFs sf = new StatFs(path);
// 获取单个数据块的大小(Byte)
long blockSize = sf.getBlockSize();
// 获取所有数据块数
long allBlocks = sf.getBlockCount();
// 返回SD卡大小
// return allBlocks * blockSize; //单位Byte
// return (allBlocks * blockSize)/1024; //单位KB
return (allBlocks * blockSize) / 1024 / 1024;
}

/**
* 判断当前内存卡是否可用
* @param mContext
* @return
*/
public static final boolean isExist(String sdPath) {
ArrayList<String> list = getExtSDCardPaths();
for (int i = 0; i < list.size(); i++) {
if(list.contains(sdPath)) {
return true;
}
}
return false;
}
}


Android手机外置SD卡(TF卡)的获取方法

    Android手机上的外置SD卡,起初的时候,即在Android出世的前几年,那时手机的存储是十分有限的,不像现在到处可见16G、32G和64G的存储,因而那时候的手机有的厂商允许插入外置的SD卡,此时这张卡仍处于手机的扩展部分。后来,随着手机的发展以及存储能力的增加,这张外置SD卡,逐渐成为了手机的一部分,不再允许可挺拔了,当然现在依然有的手机允许对存储进行拓展,比如三星等。

    那张拓展的存储卡,现在叫做TF卡,且不是所有的手机都支持它,但是有时候有些奇葩需求偏要优先存储在TF卡里面,这叫不得不要求开发人员去检查这张卡是否存在、是否可用。又因为这是手机厂商可拓展、可自定义的部分,所有不同厂商生产的手机,以及同一厂商生产的不同型号的手机,TF卡的位置都相差很大,并没有一个统一的名称或位置。因而这是比较困难的一部分,但是还好Android是开源的,我们可以通过运行时来判断手机是否有TF卡,以及TF卡是否可用。

    下面这个方法可以获取手机的可以存储,包括SD卡、TF卡等,对多存储卡进行了匹配,详细的代码如下:

     1 public class SDCardScanner {
     2     /*
     3      * avoid initializations of tool classes
     4      */
     5     private SDCardScanner() {
     6     }
     7
     8     /**
     9      * @Title: getExtSDCardPaths
    10      * @Description: to obtain storage paths, the first path is theoretically
    11      *               the returned value of
    12      *               Environment.getExternalStorageDirectory(), namely the
    13      *               primary external storage. It can be the storage of internal
    14      *               device, or that of external sdcard. If paths.size() >1,
    15      *               basically, the current device contains two type of storage:
    16      *               one is the storage of the device itself, one is that of
    17      *               external sdcard. Additionally, the paths is directory.
    18      * @return List<String>
    19      * @throws IOException
    20      */
    21     public static List<String> getExtSDCardPaths() {
    22         List<String> paths = new ArrayList<String>();
    23         String extFileStatus = Environment.getExternalStorageState();
    24         File extFile = Environment.getExternalStorageDirectory();
    25         if (extFileStatus.endsWith(Environment.MEDIA_UNMOUNTED)
    26                 && extFile.exists() && extFile.isDirectory()
    27                 && extFile.canWrite()) {
    28             paths.add(extFile.getAbsolutePath());
    29         }
    30         try {
    31             // obtain executed result of command line code of 'mount', to judge
    32             // whether tfCard exists by the result
    33             Runtime runtime = Runtime.getRuntime();
    34             Process process = runtime.exec('mount');
    35             InputStream is = process.getInputStream();
    36             InputStreamReader isr = new InputStreamReader(is);
    37             BufferedReader br = new BufferedReader(isr);
    38             String line = null;
    39             int mountPathIndex = 1;
    40             while ((line = br.readLine()) != null) {
    41                 // format of sdcard file system: vfat/fuse
    42                 if ((!line.contains('fat') && !line.contains('fuse') && !line
    43                         .contains('storage'))
    44                         || line.contains('secure')
    45                         || line.contains('asec')
    46                         || line.contains('firmware')
    47                         || line.contains('shell')
    48                         || line.contains('obb')
    49                         || line.contains('legacy') || line.contains('data')) {
    50                     continue;
    51                 }
    52                 String[] parts = line.split(' ');
    53                 int length = parts.length;
    54                 if (mountPathIndex >= length) {
    55                     continue;
    56                 }
    57                 String mountPath = parts[mountPathIndex];
    58                 if (!mountPath.contains('/') || mountPath.contains('data')
    59                         || mountPath.contains('Data')) {
    60                     continue;
    61                 }
    62                 File mountRoot = new File(mountPath);
    63                 if (!mountRoot.exists() || !mountRoot.isDirectory()
    64                         || !mountRoot.canWrite()) {
    65                     continue;
    66                 }
    67                 boolean equalsToPrimarySD = mountPath.equals(extFile
    68                         .getAbsolutePath());
    69                 if (equalsToPrimarySD) {
    70                     continue;
    71                 }
    72                 paths.add(mountPath);
    73             }
    74         } catch (IOException e) {
    75             // TODO Auto-generated catch block
    76             e.printStackTrace();
    77         }
    78         return paths;
    79     }
    80 }


    首先,我把它写成了一个工具类,因而声明了一个私有的构造器,目的就是要防止该类被实例化。

    然后,首先获取了Android标准一部分的外置SD卡,如果它可用的话。

    然后利用运行时,通过命令行函数'mount'来获取所有的存储位置,并对返回的结果进行SD卡或者TF卡的查找。

    最后返回了所有可用于存储的不同的卡的位置,用一个List来保存。由于不是所有的手机都支持TF卡,因而这个List包含的路径未必很多,只有一个SD卡的手机只会返回一个路径,多个可用存储位置的会返回多个路径。

    但有一点,是必须的,paths.get(0)肯定是外置SD卡的位置,因为它是primary external storage.

本文我们来分享三篇Android开发人员的面试经历,这些亲身的经历可以给新人或者准备面试的Android开发者提供参考。

一个Android菜鸟“面霸”的面试经历分享


今天是我入职一个创业公司的第二天。由于公司今天才把自己用的电脑买回来,只好今天在做着每一个技术人员入职第一天常做的事:安装相关开发软件,配置开发环境。

在安装软件的过程中,由于下载最新版的android studio比较缓慢,只好在下载过程中随便翻翻。然后,看到一个开发群里,一位朋友还在聊面试的事,他在那里说,今天又没有面试通知。听了之后,感慨万千,这样的感受我也有过很多次。

至于为什么敢称自己“面霸”,一来有噱头的成分,二来,确实自己面试了很多次。这不是自己有什么自豪的地方,确实是因为自己的工作经历有点特殊。差不多四年的时间,换了四份工作,每一次换工作都会不得不开始找工作。有些是因为个人发展原因,有些是因为一些公司项目组解散,公司管理方面的原因。

去年我最多的一次面试是一天赶四家面试,我以为从那以后,再也不会有这样的情况了。但是,上周找工作,一周面试了15家,除了第一天面试了一家,后面四天的面试是3个,4个,3个,4个。一天四场面试,中午都是没时间吃饭的,饿着肚子跑了一天。最后拿到了三个比较满意的offer。在上海的两年,因为换工作,上海的地铁线,除了一个最近新开的16号没走过,其余的都走过。然后也遇到过各种奇葩、坑爹的面试。面试我的人组长,主管,技术总监,CTO,老板,还有不懂技术的各种人物,有上市公司、初创公司,外包、外派公司,有互联网公司,IT公司,也有什么销售、广告、传媒、金融公司。说了这么多,不是说自己技术好,我只是因为自身的经历,看到了很多现象,才想说出来,能帮到一些找工作的朋友,就善莫大焉了。

这里简单说一下自己的情况,大专学历,之前学的机电,然后参加一个Java培训,培训之后,自己发现javaee开发需要用到的知识太多了,然后,自己刚好那个时候接触到android,于是,就想做Android开发。

第一份安卓工作,自己进去差不多就是实习生的身份,因为公司给学习机会,可以一边学习,一边跟着做项目,所以,到现在还是很感谢当初第一份工作。

当然,说到刚开始找工作,因为没有android开发经验,去网上搜了很多职位,投了简历都没反应,搜了很久才找到那家公司,要求很低,实习生都可以,我才去面试,还有上机测试,但是,因为测试的都是基础知识,然后,那家公司是在一个县级市的软件园区,估计,也因为去面试的人,加上当初自己表现的比较愿意学习,老板才给了这次机会。不管怎么说,我从心底感谢第一份工作。

这里的体会是:当你工作经验很少时,你找一个工作要付出很多努力。有很多人说,没人通知面试,面试机会少。刚开始确实是这样,但是,你自己要去找方法。比如:多在几个网站上投,不要怕他们要求高,你条件达不到,万一有面试机会呢?另外,有时间多刷刷简历,一般上午10点左右,下午2-3点左右刷一下简历,这两个点是hr看简历相对集中的时候。另外,你经验少,你要表现出两点,一、基础知识要扎实。二、愿意去学习,至少你要表现出一副以后愿意在这个方向好好学习的样子,要不然,别人干嘛要你?谁愿意去培养你。

说到基础知识扎实,有人说我不扎实,这就是你的问题了。另外,急着找工作,怎么办?

你就搜搜大多数的面试题经常问那些问题,提起多看几遍,不至于问到的时候,根本不知道说什么,至少你能说出个大概也比什么都说不出来好。当然,这不是教你诈,是你找到工作后,要赶紧把自己薄弱的地方补上来。

记得刚开始学Java时,经常会被问到一些问题,比如,Java的三大特性,抽象类与接口的区别,重载与重写,单例模式,递归算法,多线程,这些经常碰到的问题。放到安卓上,可能刚开始经常会问道一些基本的知识:比如,4大组件,5大布局,listview,Intent的使用。面试时这些最常用的知识你要知道,要说的上来吧。

刚开始工作的一两年,面试的时候,碰到出面试的公司大概90%以上,当然,这个各种公司参差不齐的,有的是自己出的有深度的题,有的是从百度上搜的一份打印的,我见过几家直接能搜到原题的面试。先不说出面试的公司怎样,说说我碰到的各种面试的,有全英的,有全部是逻辑题的,就是给你三个图形,让你推测第四个图形的,有面试安卓开发,出了一对c++和sqlserver的题的(公司是做游戏的)。有些面试题做起来真的是浪费时间,如果你感觉这家公司很不满意,就礼貌的说出来,不做了走人吧。如果是正儿八经的面试题,你做不出来时,最好能写写大致的思路,有时候也能算做对的。

说到面试题,有的公司的面试题,真的是多年不变的,我碰到过两家公司,隔一年去面试,还是那几道题,当然有家公司第一次面试过了,因为面临其他的一个机会没有去,第二次面试还是那些题,依然也过了。但是,同样的题,不同的经验,你要答出不同的答案,至少要比之前你回答的更有深度。

其实,你工作大概两三年之后,面试做面试题的公司已经很少了,但是也有15%左右,还是会有面试的。只不过,更多的会问你项目情况,一些实际的开发方面碰到的问题。

比如,现在经常会问到一些,listview的优化技巧,自定义控件的步骤,异步加载方面,jni,ndk,然后一些开源框架,开源控件的使用,并且经常被问到,这些开源控件的源码你看过没有。因为相信大家都明白,很多开源控件都用过,但是,真正去看他们源码,去改他们源码的,恐怕不多吧。还有一些框架设计,安卓源码方面的问题。当然,如果你带过团队,也会问一些团队分工,管理方面的问题。

我记得一个同学的qq签名是,能力越大,责任越大。我想到的是,人是要不断成长的,当你不断的成长的时候,你的责任是不自觉的加给你的。比如,你三年经验做的事和一年经验做的事,肯定有不少差别的,当然你们待遇也有不少差别。

面试,真的是个体力活加脑力活。你一次次面试,要学会总结,其实,从面试中,我们能学到很多东西。比如,你去一个公司面试,要记得看公司环境,地理位置,公司环境,办公室设备,都能看出一个公司资金背景情况。因为,上海这个城市,真的有很多坑爹的创业公司,说白了就是几个人想到一个app创意,就组建一个团队开始做,做不长,资金或者融资跟不上就死掉了。我面试过一家在唐镇的“公司”,我拿着地图找到那里之后,“公司”对面还有人在炒菜,闻起来应该是洋葱炒鸡蛋。公司是直接在小区里租的那种三室一厅,然后,把了七八台电脑,还不交税,直接发现金,我随便聊聊就赶紧走了。其实,这样的公司上海真的很多,见过好多小区房里面上面挂着“禁止在住宿房办公”牌子,但是里面是一个个小公司在关着门上班,第一道大门还在里面反锁着。还有一些所谓的高新园区,集电港什么的,里面一两个小房间,密密麻麻的摆了十几张电脑桌。我不知道,里面上班的人做何感想。我只能说,我们程序员真命苦,要在这样压抑的环境中上班。

所以,对于面试,我个人的推荐是,如果刚毕业,外包、外派的这样的公司,可以迅速的通过大量的项目开发提升自己的技术水平,但是,不要待的太长,除非你有机会进到管理岗位。一般不要超过两年。

两年以上经验的话,有机会进一些大公司,比如,一些大型IT公司或者互联网公司,这样最好。如果进不了大公司的话,进创业公司也是一个不错的选择,关键是,你进一个什么样的创业公司。最近几年移动互联网的发展,造成很多创业公司或者很多创业团队,想到一个点子,或者他们所谓的创意,就迅速的招三五个开发人员,开始开发,开发几个月之后,项目over了,团队解散了。对于创业公司,你一定要擦亮眼睛,进去之前,要问清楚公司做什么产品,公司的团队构成,从一些背景方面,了解公司的资金情况,在要做的产品方面的资源优势,如果产品前景不好,公司有没有资金或者资源优势,这样的创业公司你要慎重考虑了。不要轻易的听信一些面试官,或者老板的忽悠,拿什么前景忽悠你,只能说这么多了。

说一些面试的坑爹经历:

1.一家公司,在一个火车站附近的商业大厦里,进去之后,一看就三个中年人,摆了几台电脑,屋里光线很暗,上来让填一个表,刚准备写,犹豫了一下,我说,不好意思,我不喜欢这样的工作环境(太压抑了),把表还给他们,走了。

2. 有一家金融公司,准备组建团队做自己的金融app,(发现15年准备做自己金融APP的公司特别多)。进去面试,三个西装革履的人,提各种问题,从开发细节,到产品流程,到产品与开发的沟通,问得非常详细,坑爹的地方在于,三个人都拿了一个笔记本,我回到的一些问题,他们觉得重要的都记了下来。比如,我说,我们开发一般需要一个功能文档,和ui流程图、UI效果图。问了一个多小时,他们也记了一个多小时。然后,等通知,没有下文。分明就是想免费了解一些项目开发方面的东西。

3.刚来上海时,有一家公司面试要上机,一定要我建个工程,写个东西,哪怕只是一个button点击事件。

4.面试一家公司的android开发,给了一份c++测试题和一个SQLServer方面的题。我以为拿错了,又问了一下前台,她说,我们招android的就是做这个题。

5.碰到过一家公司的填表问,“你为什么要应聘工作?”、“你家庭生活怎么样?”类似的问题。

6.一个公司在居民楼里,对面的房间还在炒菜。就是上面说的,洋葱炒鸡蛋。

7.去一个比较大的公司,看到填表上有,一面,二面,三面,四面。礼仪评分,穿

着评分,口才评分....问题是,一面是10分钟结束,二面要等下次。为了这一个面试你要跑四次。遂一面之后,放弃。

8. 还是一个金融公司的面试,面试馆拿了一个厚厚的打印资料,回到问题的时候,看他翻页,无意间瞥到了首页上写着几个打字“安卓面试题集”,问的问题,乱七八糟。五大布局叫什么名字,activity的生命周期,java的三大特性,aldi叫什么,等等,很多是一些基础的,网上搜来的面试题。

9.有一家公司,打电话过去面试,我刚填完面试表,刚做完大致介绍,说,我们给不了你这么高的薪资,然后,薪资擦了一大截。然后,结束了,

10.四张全英的面试题,中间两页是逻辑图,全是什么图形推断,数字推断的题。

11.过去先做一个小时的试题,做完了说,先回去吧,我们会电话通知的...

印象比较深刻的就说这几个吧,还有其他的一些,什么过去面试等半天,不懂技术的人,揪着你一个问题一直不放的都有。

说一些面试准备方面的问题:

1.提前查好路线,乘车方式。(我一般是写在纸上,包括联系方式,然后用百度地图,不过,有定位不准的情况)

2.提前了解一下面试公司的一些职位信息,大概需要的一些技术点,可能问到的一些问题。

3.无论是多大的公司,自己多心仪的公司,或者自己不喜欢的公司,都要尽量淡然对待,保持自信,哪怕装你也要装的有自信的样子。

说一些面试收获上的东西,之前看到过一句话说,你要割一段时间就要刷新下简历,不要在一个环境里待的太久。先不说这句话的对错。不同的人有不同的理解。我是因为有些自身的经历,换工作城市,进的某些公司项目组解散,等等原因,才造成换工作比较频繁。不得不一直走在面试的路上。但是,在面试过程中,自己也确实学到了不少东西。跟一些CTO,技术经理面试,他们有的提的问题,包括给的一些建议都很中肯,有一个技术经理也跟我分享了他刚毕业几年的工作经历。还有之前去国内一个微博巨头公司下的一个游戏公司面试,那位美丽的hr负责人姐姐,也给了很多建议,让我弄清楚了自己到底想找什么样的工作。因为刚开始几年,通过跳槽,确实薪资提升比较快,但是,5年以后呢,如果技术没有深入的一个方面,恐怕就不能持续发展了。

说到上个星期之前,其实找到了一家,但是只上了一天班。第二天,我做公交做到地铁站,徘徊了很久,没有进去,就没去那家公司了,虽然那家公司给的薪资不低,离自己住的地方也进,但是,公司一些其他资源不足,能很清楚地看到那一个项目做不长,自己不想做几个月之后,再换工作。然后,才有了上周比较疯狂但是有选择的面试。

说了这么多,只是想分享一些自己的切身经历和感受,希望能给一些最近正着找工作的朋友一些帮助。每个人都有自己的独特性,存在的都是合理的,技术人千万不要唯技术论,觉得自己技术很牛,就可以目无别人,别人比你薪水高,比你受欢迎,一定有他独特的地方。每个人的经历不同,你要找到适合你的方法,你才能更好的在自己的路上走下去。

回首向来萧瑟处,也无风雨也无晴。

梦里不知身是客,一晌贪欢。


分享一下android面试经历,应届生,非211


年前不是找工作的好时间。

码头大了,船自然会来。

找工作前前后后找了差不多3个周了,我呢是应届生,非211,确切地说是大四学生,很多人应该和我差不多,如果你真的有能力,哪个公司会不要你?

写程序很多时候不是经验问题。很多时候是一个思想,回来了,开始写。

还有,我以应届生进去的,因为没有毕业证,所以先实习。

论坛还是有帮助的

11.11好像

第一家公司:新媒传信,不知道?总得知道飞信吧。好了,第一家面试,非常紧张,笔试答的本来就不好,我只说我记得的,题目挺多的,NND,根本打不完,有个算法题,优化问题,总之优化问题是用空间换时间,不过面试官说他也不会,感到平衡许多。。。。总之,各种原因 悲剧了,有人说加班多,这个到无所谓。

11.12应该

橡果国际,名字很好听的,没有笔试直接,当时坐地铁,没有直达的,还得坐bus,直接搞得我头晕,他们在4层,进去前台不在,打电话问,带回前台来了问:是不是看没人没敢进? 我汗,那是礼貌问题,直接无语了,没什么好说的,很失望,真是只有一个好名字。

后面各种小公司

挑部分说,有些我也记不住。

因为我是应届生,一般都背着电脑,有个项目是平板的。所以,,,都说丽水桥附近的骗子公司多,不知道是不是这样。有一个panyun,linux打字不爽啊,用拼音了,进去说流程40分钟,上级,一道算法,一道app,我对硬件还是挑剔的。我想开发的内存要4G才行,打开eclipse有点卡,接下来问题来了,我愁了愁cpu ATOM顿时没了做题的欲望了。

我不是说小公司怎么样,不是那个意思。

面试了差不多10家吧。

有 eico desigin的,做设计的都知道这家公司。

因为紧张,应届生没有经验啊。很多事情毕竟不知道。跟那些工作很多年,跳槽很多次的我当然没法比。

在西城区有一家公司,名字忘了。笔试不错,面试除了有点紧张。我从面试官哪儿获得了对于一个应届生的要求:

1 基础是否扎实

2 沟通意识,团队合作能力

3 吃苦能力和求知欲

这些对于我来说不是什么问题了,可是你还要找到你的缺点是什么,虽然不够致命。

前几天去AppWill面试官也是山东的,挺和气的,然后呢说了说我,普通话问题,虽然做技术的,交流问题我知道很重要。

平时说话有点快,普通话基本不说,在学校说普通话遭围观啊。

第二天AppWill说提供一个职位,当时我说考虑考虑,这是上周三,我是上周以接到京东的面试说:下周二面试。11.29号了

大家都说待遇问题,我也说说自己的观点,记得有人说如果一个人价值8k,hr砍价到7.5k,虽然砍掉了500,也凉了人家的心,如果有更好的机会人家肯定会走。后面还有,不说了。基本就是这个事。

不是每个企业都喜欢培养人的,应该叫做人才储备,对吧。

我知道很多人面试都碰壁,跟研究生我们肯定有差距,不是211也没关系,谁让我们高中贪玩呢,是吧。

业内都知道做加简历,北京很严重,朋友跟我说过,他们面试也是睁一只眼闭一只眼,我也很头疼实习就实习吧,反正没有毕业证。这样更是悲剧,原因很简单,其实吧,大家都说我精通什么什么,你说我熟悉什么什么,不说了。

其中获得了2个内部推荐,一个新浪的,一个京东了,因为新浪那个,当时没有经验,所以跟新浪无缘了,最后我准备了一周去京东面试,一顿狂轰乱炸。

面试了一个下午,终于好了,以前我也没想过能够进去,总之,作为应届生,诚实一点(如果你的撒谎能力很X,至少我不行,一下就被揭穿了)谦虚一点,肯学肯吃苦,喜欢钻研,像头说的,可能现在多拿1k,可是5年后你拿的不是1k的问题了。

有些时候目光要长远一些。

企业不是慈善机构,学校都那样。企业愿意培养你,肯定觉得你有培养的价值。

android 4源码发布了,唉这几天没心情研究源码了,现在开始下载。嘿嘿。

应届生们,加油了,我们年轻,多面试几次就行了,很多不是我们不行,只是很多我们不知道,再次谢谢各个给我面试机会的公司,谢谢各位给我提建议的面试官。也谢谢把我简历DL的HR们。

自从上大学没有过过一次圣诞节,每次圣诞都考试,烦人,这次圣诞好好放松一下吧,好好努力


android面试360经验


今天去传说中高大上的360面试了,本人原来从事j2ee的web网站开发,自学android一年,今天被打击了,题目如下仅供参考,这种大公司都是看面试官临时发挥问问题啦~~

深刻醒悟到自己对安卓的理解是多么的浅薄~~

1 activity启动模式及应用场景:重点是问singleInstance的模式下是否新启动一个task,别的应用启动这个activity在哪个task里以及跳转到别的页面如何跳转回来?

其实这个问题,论坛里有很多帖子来讲一些理论的东西啦,当然也有很多错误的,大家不能看一面之词啦,还是去官网寻找答案。(面试官面无表情,我也就说了一些我自己的想法)

设置了"singleTask"启动模式的Activity的特点: 1. 设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值 taskAffinity的任务存在;如果存在这样的任务,它就会在这个任务中启动,否则就会在新任务中启动。因此,如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。 2. 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。

加一句感觉面试真得很像相亲,有缘分怎么都聊的来,没缘分说什么感觉都交流不了,我说了上面一大段singleTask的东西后,面试官问我 singleInstance的东西,还问另一个应用程序要使用singleInstance的页面,这个activity会在哪个栈里,感觉他应该问的是这个图的情况,但是他说是singleInstance,我就说singleInstance独占一个task了。2 然后问了Dalvik虚拟机和JVM虚拟机的区别,问的程度很深,单单说处理的东西不同,运行效率不同,Dalvik多个实例运行,面试官并不满意,追问了为什么基于寄存器就快,为什么Dalvik设计成多个实例运行这个问题确实把我难住了,一直研究应用开发确实忽略了研究Dalvik虚拟机。下面是找了一些答案给亲们做参考吧~特别提示,此题千万别说基于寄存器的Dalvik比基于堆栈的jvm运行速度快,我就是这样掉坑里了,又解释不出来,悲剧了。 Dalvik虚拟机与Java虚拟机的最显著区别是它们分别具有不同的类文件格式以及指令集。Dalvik虚拟机使用的是dex(Dalvik Executable)格式的类文件,而Java虚拟机使用的是class格式的类文件。一个dex文件可以包含若干个类,而一个class文件只包括一个类。由于一个dex文件可以包含若干个类,因此它就可以将各个类中重复的字符串和其它常数只保存一次,从而节省了空间,这样就适合在内存和处理器速度有限的手机系统中使用。一般来说,包含有相同类的未压缩dex文件稍小于一个已经压缩的jar文件。Dalvik虚拟机使用的指令是基于寄存器的,而 Java虚拟机使用的指令集是基于堆栈的。基于堆栈的指令很紧凑,例如,Java虚拟机使用的指令只占一个字节,因而称为字节码。基于寄存器的指令由于需要指定源地址和目标地址,因此需要占用更多的指令空间,例如,Dalvik虚拟机的某些指令需要占用两个字节。基于堆栈和基于寄存器的指令集各有优劣,一般而言,执行同样的功能,前者需要更多的指令(主要是load和store指令),而后者需要更多的指令空间。需要更多指令意味着要多占用CPU时间,而需要更多指令空间意味着数据缓冲(d-cache)更易失效。3 然后问了项目的成就感,我说了Oauth编程被鄙视,说这是业务不能算技术;说了DeviceplocyManager,反正没什么亮点吧。各位亲们各自发挥吧,最好是能抓住面试官的兴趣。4 消息推送的时候怎么获取每台设备的id?这题完全没答上来不知道什么意思。不过我说了开发过程中用过的Mac地址加上终端编号加上CPU的序列号,android不太了解应该有相应的东西。5进程间通信为什么用aidl,socket通信,content provider不是都可以进程间通信吗?6 为什么使用 content provider 共享数据?7 listview的优化,问了item内部的recycle问题,把我问住了总体而言,这次面试感觉非常不好,主要是经常会被面试官打断再深入问另一个问题思路经常会断,好吧,自己确实没有深入的去想android系统的设计理念和实现方式。

只能给亲们提供这些东西了,亲们加油吧!


本文我们来分享一批Android开发中最常用的组件下载地址及使用说明,都是开源免费的,绝对的干货。

了解常见的开源项目,可以扩大我们的视野,知道有哪些可以利用的资源,对于我们平常的设计和开发很有好处

UI相关

  • 图片

    • ps://github.com/nostra13/Android-Universal-Image-Loader" target="_blank">Android-Universal-Image-Loader:com.nostra13.universalimageloader:异步加载、缓存、显示图片

    • ImageLoader:com.novoda.imageloader:异步加载、缓存、显示图片

    • picasso:com.squareup.picasso:功能强大的图片下载缓存库

    • PhotoView:uk\co\senab\photoview:支持缩放和各种手势的ImageView

  • ListView

    • JazzyListView:com.twotoasters.jazzylistview:扩展的ListView,当列表项目在屏幕上可见时产生动画效果

    • StickyListHeaders:com.emilsjolander.components.stickylistheaders:在ListView中置顶

    • ListViewAnimations:com.haarman.listviewanimations:带动画的ListView

    • drag-sort-listview:拖拽排序ListView的元素

    • android-swipelistview:让listview的item可以向右滑动

  • 下拉刷新

    • Android-PullToRefresh:com.handmark.pulltorefresh:下拉刷新组件

    • android-pulltorefresh:下拉刷新组件

  • 菜单

    • SlidingMenu:com.jeremyfeinstein.slidingmenu:滑动菜单

    • MenuDrawer:滑动菜单组件

  • Action Bar

    • ActionBarSherlock:com.actionbarsherlock:Action Bar组件

    • android-actionbar:Action Bar组件

    • GlassActionBar:玻璃效果的Action Bar

  • ViewPager

    • Android-ViewPagerIndicator:com.viewpagerindicator:分页显示组件

    • PagerSlidingTabStrip:com.astuetz.viewpager:页面滑动组件

    • JazzyViewPager:可自定义动画的ViewPager

  • 兼容

    • NineOldAndroids:com.nineoldandroids:移植Honeycomb版本的动画API到旧版本上

    • HoloEverywhere:移植Android 4.1的Holo主题到旧的版本上

    • GlowPadBackport:GlowPadBackport:移植Android 4.2 GlowPadView到旧版本上

    • android-switch-backport::移植Android 4的Switch widget到旧版本上

  • AChartEngine:org.achartengine:Android上的绘图库

  • android-viewflow:com.taptwo.android.widget:视图切换的效果

  • android-flip:翻页动画组件

  • Android-AppMsg::In-layout notifications

  • android-wheel:kankan.wheel:Android滚动控件

  • Android-ProgressFragment:等待数据的时候,支持显示等待符号的Fragment控件

  • StaggeredGridView:瀑布流GridView布局

  • Cards-UI:卡片布局

  • cardslib:卡片布局

WebApp

  • Cordova:org.apache.cordova:Cordova是PhoneGap贡献给Apache后的开源项目,是从PhoneGap中抽出的核心代码

  • HtmlSpanner:net.nightwhistler.htmlspanner:Android上的网页渲染库,可渲染CSS

  • ChromeView:Chrome内核移植的WebView

推送

  • 个推:com.igexin:手机推送服务

  • JPush:???:极光推送

  • 百度推送:com.baidu.android.pushservice:百度推送服务

  • MQTT:ibm.mqtt:MQTT协议,似乎和推送有关系

语音识别

  • 讯飞SDK:com.iflytek:科大讯飞语音SDK

  • 百度语音识别:com.baidu.voicerecognition:百度语音识别SDK

  • mobvoi:com.mobvoi:移动语音搜索

  • 云知声:cn.yunzhisheng:云知声语音处理

音频视频图像

  • CC视频:com.bokecc:视频云平台

  • Vitamio:io.vov.vitamio:多媒体开发框架

  • leptonica:com.googlecode.leptonica:图像处理库

  • tesseract-ocr:com.googlecode.tesseract:图像OCR库

  • aacdecoder-android:com.spoledge.aacdecoder:Android上的Audio (AAC) 解码器

地图定位

  • 百度定位:com.baidu.location:百度地图SDK

  • 百度地图:com.baidu.mapapi:百度地图SDK

  • amap:com.amap.api,com.autonavi:高德地图API

  • 图吧SDK:com.mapbar:图吧地图API

  • MapABC:com.mapabc:MapABC地图SDK

广告平台

  • 友盟SDK:com.umeng:友盟统计、自动更新、用户反馈、社会化组件

  • 多盟:cn.domob:多盟平台

  • 百度移动联盟:com.baidu.mobads:百度移动联盟

  • google ads:com.google.ads:google广告

  • AdChina:com.adchina:易传媒广告平台

  • AdsMogo:com.adsmogo:芒果移动广告平台

  • Adwo:com.adwo:安沃移动广告平台

  • mobisage:com.mobisage:艾德思奇移动广告平台

  • Miaozhen:com.miaozhen:秒针第三方广告平台

  • AdMaster:cn.com.admaster:admaster广告平台

  • 易积分:com.qiang.escore:易积分移动广告平台

  • inmobi:com.inmobi:国外的广告平台

  • 点信传媒:cn.dx:广告平台

统计分析

  • Flurry:com.flurry:国外流行的统计工具

  • 百度移动统计:com.baidu.mobstat:百度开发者中心

  • Cobub Razor:com.wbtech.ums:移动统计分析工具

  • google analytics:com.google.analytics:google统计

  • lotuseed:com.lotuseed:莲子统计

  • Localytics:com.localytics.android:国外统计分析工具

  • comscore:com.comscore:国外的统计工具

网络通信

  • volley:com.android.volley:Android网络通信库

  • Apache Thrift:com.apache.thrift:远程服务调用框架

  • Netty:org.jboss.netty:异步事件驱动的网络应用程序框架

Http访问

  • Apache HttpClient:org.apache.http

  • android-async-http:com.loopj:异步Http库

  • async-http-client:异步Http和WebSocket库

  • OkHttp:实现了Google开发的SPDY协议,更快的网络传输和加载速度

XMPP协议

  • smack:org.jivesoftware.smack:XMPP客户端类库

  • Jbosh:com.kenai.jbosh:XMPP BOSH规范的Java实现

应用授权

  • Scribe:org.scribe:简单的OAuth认证

  • QQ互联:com.tencent.tauth:QQ互联

  • 百度授权:com.baidu.oauth:百度应用授权

  • weibo授权:com.sina.sso:新浪微博应用授权

社交分享

  • ShareSDK:cn.sharesdk:App分享库

  • facebook-android-sdk:com.facebook:Facebook SDK

  • 腾讯微信:com.tencent.mm:腾讯微信SDK

  • 腾讯微博:com.tencent.weibo:腾讯微博SDK

  • weiboSDK:com.weibo.sdk:新浪微博SDK

  • qweibo:com.mime.qweibo:Q版微博

  • t4j:t4j:网易微博开放平台

  • yixin:im.yixin:易信开放平台

  • 人人SDK:com.renren.api:人人网SDK

  • 翼聊:com.yiliao.android:中国电信天翼开放平台

  • evernote:com.evernote:Evernote API

  • 有道云笔记SDK:com.youdao.note:有道云笔记SDK

移动支付

  • alipay:com.alipay:支付宝

  • tenpay:com.tenpay:QQ财付通

  • umpay:com.umpay:联动优势支付平台

  • 银联支付:com.unionpay:中国银联手机支付平台

  • MMBilling:mm.purchasesdk:中国移动应用内计费SDK

Data解析

  • dom4j:org.dom4j:XML解析库

  • xmlpull:org.xmlpull.v1:XML解析器,Android自带

  • FastJSON:com.alibaba.fastjson:JSON解析器

  • Sparta:com.hp.hpl.sparta:XML、DOM、XPath解析器

  • jsoup:org.jsoup:HTML解析器

  • osbcp-css-parser:com.osbcp.cssparser:CSS解析器

  • HtmlCleaner:org.htmlcleaner:Html清洗解析库

  • Mime4J:org.apache.james.mime4j:MIME邮件格式解析器

序列化

  • google-gson:com.google.gson:序列化反序列化Java对象成Json数据

  • Jackson:org.codehaus.jackson:序列化反序列化Java对象成Json数据

ORM

  • OrmLite:com.j256.ormlite:Java ORM库

  • greenDAO:Android ORM for SQLite

  • AndrOrm:An ORM for Android

网盘

  • PCS:com.baidu.pcs:百度个人云存储

  • vdisk:com.vdisk:微盘开放平台

  • 金山快盘:com.kuaipan:金山快盘开放平台

异常收集分析

  • acra:org.acra:Application Crash Reports for Android

  • Crittercism:com.crittercism:为开发者提供分析诊断应用崩溃的原因

服务器

  • SwiFTP:org.swiftp:Android平台的FTP服务器

  • android-webserver:com.bolutions.webserver:Android平台的Web服务器

Event Bus

  • EventBus:de.greenrobot.event:an Android optimized publish/subscribe event bus

  • otto:基于Guav的Event Bus

Dependency Injection

  • RoboGuice:roboguice:Android平台的Dependency Injection框架

  • roboguice-sherlock:com.github.rtyley:使用RoboGuice实现的ActionBarSherlock

  • Google Guice:com.google.inject:Dependency Injection框架

图标资源

  • Androton-Action-Bar-Icons:一个针对Android 优化过的ICON图标集

  • http://iconsparadise.com/

  • http://iconbench.com/

  • http://www.androidicons.com/

  • https://code.google.com/p/android-ui-utils/

其他组件

  • android-query:com.androidquery:异步任务和操作UI元素

  • ZXing:com.google.zxing:条形码和二维码生成和解码库

  • pinyin4j:net.sourceforge.pinyin4j:中文和拼音转换

  • protobuf:com.google.protobuf:protobuf

  • JZlib:com.jcraft.jzlib:Java实现的zlib库

  • zt-zip:压缩解压库

  • aFileChooser:???:文件浏览器

  • image-chooser-library:???:图片和视频的选择库

  • TOML::跨语言的配置信息存取方案

  • OpenUDID:org.openudid:通用且持久的Unique Device IDentifier (UDID)解决方案

  • Parse:com.parse:各种很棒的后台服务

  • Codec:org.apache.codec:字符串编码解码库

  • jChardet:org.mozilla.intl.chardet:自动检测字符集

  • JRegex:jregex:正则表达式库

  • SQLCipher:info.guardianproject.database:Android数据库加密

  • xiaomi:com.xiaomi:小米开发者平台:推送服务、自动更新、自动发布等

  • DataDroid::以RESTful方式管理数据

  • Afinal::SQLITE的ORM和IOC框架,同时封装了android中的http框架

  • AndroidCommon:Android常用的一些库和功能,如缓存,下拉列表,下载管理,静默安装等

  • ThinkAndroid::Android整体框架:集成了ioc,orm,下载,缓存等模块,能让开发更加快速和高效

不常用组件

  • dnsjava:org.xbill.dns:域名解析

  • sasl:com.novell.sasl.client:sasl认证机制

  • LuaJava:org.keplerproject.luajava:Java嵌入Lua

  • PJSIP:org.pjsip.pjsua:PJSUA是一个开源的命令行SIP用户代理(软电话),用PJSIP协议,PJNATH,和PJMEDIA实现




UI框架

  • GreenDroid

  • Bearded-Hen/Android-Bootstrap

  • donnfelker/android-bootstrap

游戏引擎

  • cocos2d-x

  • libgdx

  • AndEngine

  • MonoGame

其他组件

  • skrollr:视差滚动Javascript引擎

  • androidannotations:扩展Android注解语言

  • android_guides:学习Android和iOs

  • phonegap:WebApp开发引擎


[!--infotagslink--]

相关文章

  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • C#创建自定义控件及添加自定义属性和事件使用实例详解

    这篇文章主要给大家介绍了关于C#创建自定义控件及添加自定义属性和事件使用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-06-25
  • JS实现自定义简单网页软键盘效果代码

    本文实例讲述了JS实现自定义简单网页软键盘效果。分享给大家供大家参考,具体如下:这是一款自定义的简单点的网页软键盘,没有使用任何控件,仅是为了练习JavaScript编写水平,安全性方面没有过多考虑,有顾虑的可以不用,目的是学...2015-11-08
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • C#窗体布局方式详解

    这篇文章主要介绍了C#窗体布局方式详解的相关资料,需要的朋友可以参考下...2020-06-25
  • Android模拟器上模拟来电和短信配置

    如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
  • 夜神android模拟器设置代理的方法

    夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • Android WebView加载html5页面实例教程

    如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
  • 深入理解Android中View和ViewGroup

    深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
  • Android自定义WebView网络视频播放控件例子

    下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
  • 自定义jquery模态窗口插件无法在顶层窗口显示问题

    自定义一个jquery模态窗口插件,将它集成到现有平台框架中时,它只能在mainFrame窗口中显示,无法在顶层窗口显示. 解决这个问题的办法: 通过以下代码就可能实现在顶层窗口弹窗 复制代码 代码如下: $(window.top.documen...2014-05-31
  • Android用MemoryFile文件类读写进行性能优化

    java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
  • 自定义feignClient的常见坑及解决

    这篇文章主要介绍了自定义feignClient的常见坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-20
  • Android设置TextView竖着显示实例

    TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
  • android.os.BinderProxy cannot be cast to com解决办法

    本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20
  • pytorch 自定义卷积核进行卷积操作方式

    今天小编就为大家分享一篇pytorch 自定义卷积核进行卷积操作方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-06
  • PHP YII框架开发小技巧之模型(models)中rules自定义验证规则

    YII的models中的rules部分是一些表单的验证规则,对于表单验证十分有用,在相应的视图(views)里面添加了表单,在表单被提交之前程序都会自动先来这里面的规则里验证,只有通过对其有效的限制规则后才能被提交,可以很有效地保证...2015-11-24
  • Android 实现钉钉自动打卡功能

    这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
  • Android 开发之布局细节对比:RTL模式

    下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02