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) | 
