Android實驗參考目錄
常用知識點總結
服務綁定bind Service
MathService.java,提供綁定,解綁定,加法的服務
package com.example.pprp.servicebind;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class MathService extends Service {
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder
{
MathService getService(){
return MathService.this;
}
}
public MathService() {
}
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(this,"本地邦定:mathservice",Toast.LENGTH_SHORT).show();
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Toast.makeText(this,"取消綁定:mathservice",Toast.LENGTH_SHORT).show();
return false;
}
public long Add(long a, long b)
{
return a+b;
}
}
MainActivity.java
bindService()需要參數:ServiceConnection對象,在ServiceConnection對象中可以獲得一個mathService對象。依然用Intent來開啟service
package com.example.pprp.servicebind;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button btn_bind, btn_unbind,btn_calc;
private TextView tv;
private MathService mathService;
private boolean isBind =false;
private ServiceConnection mCon = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mathService = ((MathService.LocalBinder)iBinder).getService();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mathService = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
tv = (TextView)findViewById(R.id.tv);
btn_bind = (Button)findViewById(R.id.btn_bind);
btn_calc = (Button)findViewById(R.id.btn_calc);
btn_unbind = (Button)findViewById(R.id.btn_unbind);
btn_bind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(!isBind)
{
final Intent serviceIntent = new Intent(MainActivity.this,MathService.class);
//startService(serviceIntent);
bindService(serviceIntent,mCon, Context.BIND_AUTO_CREATE);
isBind = true;
}
}
});
btn_calc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(mathService == null)
{
tv.setText("UNBIND!");
return;
}
long a = Math.round(Math.random()*100);
long b = Math.round(Math.random()*100);
long result = mathService.Add(a,b);
String msg = String.valueOf(a)+"+"+String.valueOf(b)+"="+String.valueOf(result);
tv.setText(msg);
}
});
btn_unbind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(isBind)
{
isBind=false;
unbindService(mCon);
mathService=null;
}
}
});
}
}
注冊問題:貌似只要是通過new出來的service就不用人工注冊了
ThreadService使用總結
MyThreadService.java文件:
構造一個Runnable對象(用於產生隨機數),分別在onCreate()中new一個thread,在onStart()中開啟thread,在onDestory()中中斷thread。
package com.example.pprp.threadtest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyThreadService extends Service {
public MyThreadService() {
}
private Thread workThread;
private Runnable backWork = new Runnable() {
@Override
public void run() {
try{
while(!Thread.interrupted())
{
double randomDouble = Math.random();
MainActivity.UpdateGUI(randomDouble);
Thread.sleep(1000);
}
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
};
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this,"oncreate()",Toast.LENGTH_SHORT).show();
workThread = new Thread(null,backWork,"workThread");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(this,"onstart()",Toast.LENGTH_SHORT).show();
if(!workThread.isAlive())
{
workThread.start();
}
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"ondestroy()",Toast.LENGTH_SHORT).show();
workThread.interrupt();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
}
MainActivity.java:
創建一個Runnable對象(用來更新線程,必須使用handler),聲明靜態TextView, new 一個靜態Handler, new一個Intent來開啟service, 通過button的事件函數觸發事件,分別開啟服務和關閉服務。
package com.example.pprp.threadtest;
import android.app.Activity;
import android.content.Intent;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
static TextView tv;
Button st,ed;
private static double randomDouble;
private static Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
tv = (TextView)findViewById(R.id.tv);
st = (Button)findViewById(R.id.btn_start);
ed = (Button)findViewById(R.id.btn_stop);
final Intent serviceIntent = new Intent(this,MyThreadService.class);
st.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startService(serviceIntent);
}
});
ed.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
stopService(serviceIntent);
}
});
}
public static void UpdateGUI(double refreshDouble)
{
randomDouble = refreshDouble;
handler.post(refreshRunnable);
}
private static Runnable refreshRunnable = new Runnable() {
@Override
public void run() {
tv.setText("output"+String.valueOf(randomDouble));
}
};
}
Service用法總結
new一個service出來:
package com.example.pprp.servicetest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this,"oncreate()!!",Toast.LENGTH_LONG).show();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(this,"onstart()!!",Toast.LENGTH_LONG).show();
double randomDouble = Math.random();
String msg = "RANDOM OUOTPUT :" + String.valueOf(randomDouble);
Toast.makeText(this,msg,Toast.LENGTH_LONG).show();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"ondestory()!!",Toast.LENGTH_LONG).show();
}
}
注冊,修改AndroidManifest.xml文件中的內容
<service
android:name=".MyService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.pprp.servicetest"/>
</intent-filter>
</service>
在主Activity中的用法:
package com.example.pprp.servicetest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainA extends AppCompatActivity {
Button st,ed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
st = (Button)findViewById(R.id.btn_start);
ed = (Button)findViewById(R.id.btn_stop);
final Intent ServiceIntent = new Intent(this,MyService.class);
st.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startService(ServiceIntent);
}
});
ed.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
stopService(ServiceIntent);
}
});
}
}
Broadcast Receiver用法
broadcast receiver應該通過new的方式新建,比較好,需要添加幾行代碼
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.pprp.intenttest">
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".childA" />
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="tttesttt"/>
</intent-filter>
</receiver>
</application>
</manifest>
MyReceiver.java
package com.example.pprp.intenttest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
String msg = intent.getStringExtra("key1");
Toast.makeText(context,msg,Toast.LENGTH_SHORT).show();
}
}
onCreate中涉及到的部分:這里tttesttt跟AndroidManifest.xml文件中的一致
String UNIQUE_STRING="tttesttt";
btn_broad.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(UNIQUE_STRING);
intent.putExtra("key1","thisis1test");
sendBroadcast(intent);
}
});
Intent使用注意事項
首先,應該使用new Activity的方法來創建子程序,盡量不要手動創建,如果手動創建還需在AndroidManifest.xml文件中添加相應的部分
然后,調用子activity的時候,如果用startActivityForResult,才會有返回值,才能寫onActivityResult函數;如果用startAcitivity則不會運行該函數。
1. Intent使用方法
如果發送Intent是:
Uri data = Uri.parse("message string");
Intent intent = new Intent(null,data);
setResult(intent);
那么解析的時候應該是:(父部分的處理)
Uri uridata = data.getData();
tv.setText(uridata.toString());
如果發送Intent是:
Intent intent = new Intent();
intent.putExtra("Name",et.getText().toString());
那么應該用以下方式進行解析:
Uri uridata = data.getData();
tv.setText(uridata.getStringExtra("Name"));
2. 父activity得到子activity的消息
父Activity在btn事件函數中調用子Activity:
Intent intent = new Intent(MainActivity.this,Subsub.class);
startActivityForResult(intent,SUB);
子Activity在btn事件函數中進行Intent發送:
Uri data = Uri.parse(et.getText().toString());
Intent result = new Intent(null,data);
setResult(RESULT_OK,result);
finish();
父Activity中的onActivityResult函數中的內容,用於處理子Activity發送內容
if(requestCode == SUB)
{
if(resultCode == RESULT_OK)
{
Uri uriData = data.getData();
System.out.println("result: " + uriData.toString());
tvs.setText(uriData.toString());
}
}
3. 子activity得到父activity的內容
父activity:
Intent intent = new Intent(MainActivity.this,ChildActivity.class);
intent.putExtra("Name",et.getText().toString());
startActivityForResult(intent,SUBACTIVITY);
子Activity進行接收:
Intent data = getIntent();
tv.setText(data.getStringExtra("Name"));
ListView用法總結
提前需要做的工作:在res目錄下new一個menu文件,添加一個Item
主要的用法:
//聲明ArrayList, ArrayAdapter
ListView lv;
ArrayList<String> list;
ArrayAdapter<String> adp;
//在onCreate函數中進行如下操作:
lv = (ListView)findViewById(R.id.lv);
list = new ArrayList<String>();
adp = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list);
lv.setAdapter(adp);
//btn事件函數操作:
String ans = "";
ans += et_cls.getText().toString();
ans += et_stuno.getText().toString();
ans += et_name.getText().toString();
ArrayAdapter temp_adp = (ArrayAdapter) lv.getAdapter();
temp_adp.add(ans);
//listView的事件函數:
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, final int pos, long l) {
if(l > 0)
{
System.out.println("test");
PopupMenu popup = new PopupMenu(MainActivity.this,view);
popup.getMenuInflater().inflate(R.menu.del,popup.getMenu());
popup.show();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch(item.getItemId())
{
case R.id.del:
ArrayAdapter temp = (ArrayAdapter)lv.getAdapter();
temp.remove(temp.getItem(pos));
return true;
default:
return false;
}
}
});
}
}
});
完整代碼:
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String msg = et.getText().toString();
ArrayAdapter tp = (ArrayAdapter)lv.getAdapter();
tp.add(msg);
}
});
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, final int pos, long l) {
if(l > 0)
{
PopupMenu popup = new PopupMenu(MainActivity.this,view);
popup.getMenuInflater().inflate(R.menu.menu1,popup.getMenu());
popup.show();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if(item.getItemId() == R.id.ddelete)
{ Toast.makeText(MainActivity.this,"ddlete",Toast.LENGTH_SHORT).show();
ArrayAdapter<String> tmp = (ArrayAdapter)lv.getAdapter();
tmp.remove(tmp.getItem(pos));
}
else if(item.getItemId() == R.id.oopen)
{
Toast.makeText(MainActivity.this,"oopen",Toast.LENGTH_SHORT).show();
}
else if(item.getItemId() == R.id.nnew)
{
Toast.makeText(MainActivity.this,"nnew",Toast.LENGTH_SHORT).show();
}
return false;
}
});
}
}
});
spinner 用法
spn = (Spinner)findViewById(R.id.spinner);
List<String> list = new ArrayList<String>();
list.add(0,"test1");
list.add(1,"test2");
list.add(2,"test3");
ArrayAdapter<String> adp = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,list);
adp.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spn.setAdapter(adp);
spn.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if(l > 0)
{ tv.setText(adapterView.getItemAtPosition(i).toString());
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
ArrayAdapter的用法總結
lv = (ListView)findViewById(R.id.lv);
list = new ArrayList<String>();
adp = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list);
ArrayAdapter tp = (ArrayAdapter)lv.getAdapter();
tp.add("your String");
tp.remove(tp.getItem(pos));
遇到的問題
Installation failed with message Invalid File
這個問題詳細報錯如下:
Installation failed with message Invalid File:
C:\Android\workspace\Calculator\app\build\intermediates\split-apk\debug\slices\slice_9.apk.
It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing.
通過谷歌搜索到stackoverflow上的內容:
其中最好的解決方案如下:
Click Build tab ---> Clean Project
Click Build tab ---> Build APK
Run.
親測有效
版本不匹配導致的gradle編譯出錯
這時候應該打開GradleScripts目錄下的 build.gradle(Module:app),
然后進行修改:
android {
compileSdkVersion 26
buildToolsVersion "27.0.3"
defaultConfig {
applicationId "com.example.administrator.calculator"
minSdkVersion 25
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
修改:minSdkVersion 和 compileSdkVersion 等,到你想要的版本
Error:Failed to find target with hash string 'android-26' in: D:\programFile
國內無法訪問google的關於android的庫,可以選擇國內的鏡像網站(百度經驗中就有),也可以使用VPN(百度搜索android studio VPN)就可以了,
除此以外有時候真的還是要靠運氣
需要注意:
版本高的API兼容版本低的API,反之不可行。
- 模擬器已經打開但是運行時找不到對應的模擬器
找到模擬器的adb文件,如果用的是Android原裝adb:
cd C:\Android\sdk\platform-tools
adb connect 127.0.0.1:62001
即可。
如果使用的是夜神模擬器:
cd ../..
cd "Program Files (x86)"/Nox/bin
nox_adb connect 127.0.0.1:62001
即可。
sqlite3 進入運行時遇見報錯:
error: no devices/emulators found
解決方案:首先需要明確,必須要先打開模擬器,然后使用哪個模擬器,就要找對應模擬器的adb可執行文件:
如果用的是Android的原裝sdk中的模擬器:
cd C:\Android\sdk\platform-tools
adb shell
如果用的是夜神模擬器:
cd "Program Files (x86)"/Nox/bin
nox_adb shell
即可。
sqlite3中進入shell以后,如果遇到以下報錯:
mkdir failed for , Read-only file system
可以用以下命令進行解決:
adb shell
mount -o remount rw /
Android Studio快捷鍵
快捷鍵 | 說明 |
---|---|
Ctrl+D | 復制一行 |
Ctrl+Y | 刪除當前行 |
Ctrl+G | 快捷定位某行 |
Ctrl+/ | 注釋一行 |
Ctrl+E | 查看最近打開的文件 |
Ctrl+N | 查找類名,文件名 |
Ctrl+O | 顯示父類中可覆寫方法(常用) |
Ctrl+F | 類內搜索 |
Ctrl+R | 查找替換 |
Ctrl+J | 自動代碼(自動提示) |
Ctrl+H | 顯示類的繼承結構 |
Ctrl+W | 選中代碼,類似雙擊效果 |
Ctrl+shift+"+/-" | 折疊,展開代碼塊 |
Alt+Q | 上下文信息 |
Ctrl+Alt+Shift+f8 | 臨時斷電 |
Ctrl+Shift+J | 合並行和文本,例如多行注釋,if(){} |
Alt+Shift+Up/Down | 移動上下行 |
shift+f6 | 全局重命名(或者quick fix) |