• Android移动软件开发总结


    Android实验参考目录

    1. Android生命周期

    2. UI设计-Android计算器

    3. Android UI ListView用法

    4. Intent组件通信

    5. 线程的使用-计时器

    6. 数据的存储与访问sqlite

    常用知识点总结

    服务绑定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:AndroidworkspaceCalculatorappuildintermediatessplit-apkdebugslicesslice_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:Androidsdkplatform-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:Androidsdkplatform-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)

    Android 界面设计实用工具

    颜色代码

    常用颜色搭配

    Android常用Theme

    Android美化

  • 相关阅读:
    LocalDate、LocalTime、LocalDateTime示例
    Instant时间戳示例
    Mybatis面试题
    SpringMVC面试题
    Spring面试题
    redis面试题
    计算机网络面试题
    java集合面试题
    java基础面试题
    MySQL面试题汇总
  • 原文地址:https://www.cnblogs.com/pprp/p/9582454.html
Copyright © 2020-2023  润新知