一、题目:设计一个APP

1.设计一个APP。
(1)APP中有四个界面。
(2)主界面(MainActivity)上有选项菜单,包含三个菜单项:“SD卡存储”、“启动信息获取服务”和“音乐播放器”,分别点击菜单项后各打开一个新界面(NewActivity1,NewActivity2,NewActivity3)。还有一个文本框EditView,当点击“音乐播放器”按钮后,可以将文本框的内容显示在“音乐播放器”NewActivity3的界面上。
(3)新界面(NewActivity1)上有“生成随机数”、“写入SD卡”和“返回主界面”三个按钮。当点击“生成随机数”按钮后,可以生成5个随机整数(0-100),当点击“写入SD卡”按钮后,可以将产生的随机整数写入SD卡。当点击“返回主界面”按钮后,返回主界面,不带回任何数据信息。
(3)新界面(NewActivity2)上有“启动服务”、“取消服务”、“比较大小”和“返回主界面”四个按钮。当点击“启动服务”按钮后,可以绑定服务,当点击“取消服务”按钮后,则解除绑定。当点击“比较大小”按钮后,可以实现两个整数的大小比较。当点击“返回主界面”按钮后,返回主界面,不带回任何数据信息。
(4)新界面(NewActivity3)上有“启动播放器”、“停止播放器”和“返回主界面”三个按钮,实现音乐播放功能。

二、界面展示

主页面

点击菜单栏后显示的选项

生成随机数页面

获取服务页面

音乐播放页面

三、MainActivity主页面详解

因为在本次的题目中要求要用menu菜单栏去打开子页面,所以为了方便后续调整,可以用XML文件去制作菜单资源,然后通过inflate()函数映射到程序代码中。
用这种方法时,需要一开始在res文件夹下新建一个menu的文件夹,并创建一个名为menu_main.xml的文件。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/main_menu_0"android:title="SD卡存储"/><itemandroid:id="@+id/main_menu_1"android:title="启动信息获取服务"/><itemandroid:id="@+id/main_menu_2"android:title="音乐播放器"/>
</menu>

然后在主页面中加下面的一个调用menu菜单的函数并书写选项框架。

    @Overridepublic boolean onCreateOptionsMenu(Menu menu){getMenuInflater().inflate(R.menu.menu_main,menu);return true;}

选项框架

    @Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case R.id.main_menu_0:return true;case R.id.main_menu_1:return true;case R.id.main_menu_2:return true;default:return false;}}

主页面的具体框架就只有这么多了,接着就是往case里面写内容。因为这个菜单里前两个要实现的功能是一样的,只有第三个要带值传回到子页面3中,所以也就是说子页面3要多加一个putExtra去传送数据到我们的子页面,而这三个选项的内容在上机3内也有详细讲过,所以在此不做赘述,代码在后文会po上来。

四、NewActivity1子页面1详解

按题目来看,我们创建三个按键,第一个按键是把生成的随机数用TextView显示出来;第二个按键是把生成的随机数存入到SD卡中;第三个按键是需要返回主页面。
返回主页面代码:

        returnmain.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {setResult(RESULT_CANCELED, null);finish();}});

因为返回主页面这个功能在接下来的三个页面都有,所以这里就只放一次了。
再回到子页面1,子页面1在运行前需要在AndroidManifest.xml 中注册两个用户权限,分别是加 载卸载文件系统的权限和向外部存储器写入数据的权限,代码如下:

    <uses-sdk android:minSdkVersion="14" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

第一个按键,把生成的随机数用TextView显示出来。
在这里,最简单的就是for用循环,显示出五个随机数,随机数调用Math.random()函数来获得,显示要用到TextView。

num = "";
for (int i = 0; i < 5; i++) //生成几个随机数
{num += Math.round(Math.random() * 100) + "\n";//生成100以内整数textView2.setText(num);
}

在这里的num = " "是将上一次生成的五个随机数清空,因为如果没有这行代码,页面里面生成的随机数只会在上一次的随机数基础上继续往下写。
第二个按键,把生成的随机数存入到SD卡中。

                        String fileName = "SdcardFile-" + System.currentTimeMillis() + ".txt";File dir = new File("/sdcard/");if (dir.exists() && dir.canWrite()) {File newFile = new File(dir.getAbsolutePath() + "/" + fileName);FileOutputStream fos = null;try {newFile.createNewFile();if (newFile.exists() && newFile.canWrite()) {fos = new FileOutputStream(newFile);fos.write(num.getBytes());textView1.setText(fileName + "文件写入SDcard");}} catch (Exception e) {// TODO: handle exceptione.printStackTrace();} finally {if (fos != null) {try {fos.flush();fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

因为是拿来主义(书上的代码),所以就不详细解释了。主要是获取存入SD卡的路径(利用File dir获得),System.currentTimeMillis()函数来获取当前时间来写成存入txt的文件名。

五、NewActivity2子页面2及ServiceForFile文件详解

在子页面2中,想要比较两个数的大小就必须先绑定服务,用到bind()函数,如果服务未绑定或者已解绑,就无法比较两个数。
绑定服务代码如下:

public void onClick(View v) {if(!isBound){final Intent serviceIntent = new Intent(NewActivity2.this,ServiceForFile.class);bindService(serviceIntent,mConnection, Context.BIND_AUTO_CREATE);isBound = true;}}

这里创建的Intent()方法是为了把NewActivity2传到ServiceForFile中,因为在bind共能力,除了要写子页面2的Java文件以外还需要创建一个Service的Java代码为子页面2服务。
然后用到bindService去粘合Service,使这两个Java代码联系起来。
在这里isBound=true表示服务已经绑定。
以下是取消绑定的代码。

public void onClick(View v) {if(isBound){isBound = false;unbindService(mConnection);mathService = null;}}

在比较大小的按钮中,需要先判断服务有没有被绑定,如果服务已经被绑定,才可以用随机数去生成两个数并比较大小,如果服务没有被绑定,就会TextView上提示“服务未绑定”。

 if (mathService == null){labelView.setText("未绑定服务");return;}

如果mathService != null,则表示已绑定服务,这个时候就定义两个数被随机数赋值,并用if语句判断,大的数赋值给第三个数(也可以直接输出)。

                    long num = Math.round(Math.random() * 100) ;long num2 = Math.round(Math.random() * 100) ;long num3 = 0;if(num > num2 ){num3 =num;labelView.setText(num+"和"+num2+"相比,"+num3+"大。");}else if (num2 > num){num3 =num2;labelView.setText(num+"和"+num2+"相比,"+num3+"大。");}else if(num == num2)labelView.setText(num+"和"+num2+"相比,"+num+"和"+num2+"一样大。");

在子页面2的功能都完成了的情况下,还需要创建一个连接服务的对象并将其实例化,代码如下:

    private ServiceConnection mConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {mathService = ((ServiceForFile.LocalBinder)service).getService();}@Overridepublic void onServiceDisconnected(ComponentName name) {mathService = null;}};

而在获取绑定服务的Java文件中,该Java继承于Service,创建service类Java文件的方法:

我们需要建立一个本地的绑定类,其权限为public,在这个Java文件中,我们获取到的服务会返回给自己。

    public class LocalBinder extends Binder {ServiceForFile getService() {return ServiceForFile.this;}}

绑定和取消绑定的代码如下,分别调用onBind()和onUnbind()函数。

    @Overridepublic IBinder onBind(Intent intent) {Toast.makeText(this, "本地绑定:MathService",Toast.LENGTH_SHORT).show();return mBinder;}@Overridepublic boolean onUnbind(Intent intent){Toast.makeText(this, "取消本地绑定:MathService",Toast.LENGTH_SHORT).show();return false;}

六、NewActivity3子页面3及ServiceForMusic文件详解

由题目可知,我们需要获取从主页面中得到的信息,所以要在布局文件中新建一个TextView以获取主页面的文本并把它显示在子页面3中。
在这里,仿照上机3的部分代码来实现这个功能,在此不做赘述。

        Intent intent1 = getIntent();String msg = intent1.getStringExtra("editText");txt2.setText(String.valueOf(msg));

接着,需要用到两个按钮,分别是开启音乐播放器和关闭这个播放器,是的,也要用到Service类,其创建方式和上面的ServiceForFile是一样的,在这里,要用到*.this.startService(intent);来开启*的服务(这里的星号是我们创建这个Java文件的名字);并用到*.this.stopService(intent);来停止当前活动的服务。
最后,创建一个Menu来进行菜单设置,代码如下:

    @Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.menu_music, menu);return true;}

这里的menu_music.xml是在res文件夹下的menu文件夹中创建的,加上前面的menu_main.xml文件,也就是说menu文件夹中一共有两个XML文件。
如下图所示:

menu_music.xml文件代码如下:

<menu xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:android="http://schemas.android.com/apk/res/android"><item android:id="@+id/menu_settings"android:title="@string/menu_settings"android:orderInCategory="100"app:showAsAction="never" />
</menu>

而在Service的Java文件中,首先需要重写onBind()方法这样才能将子页面3和后台服务绑定起来。

    public IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}

接着需要重写onCreate()方法,在这里需要创建音乐播放器(利用Context,然后从raw文件夹中获得音乐),然后用浮窗提示我们正在创建后台服务。

    public void onCreate(){super.onCreate();play = MediaPlayer.create(this, R.raw.music0);Toast.makeText(this, "创建后台服务...", Toast.LENGTH_LONG).show();}

重写onStartCommand()方法,传送数据、发送请求和请求的ID。

    public int onStartCommand(Intent intent, int flags, int startId){super.onStartCommand(intent, flags, startId);play.start();Toast.makeText(this, "启动后台服务程序,播放音乐...", Toast.LENGTH_LONG).show();return START_STICKY;}

最后要用到销毁服务的方法onDestroy(),释放音乐播放器并销毁该进程。

    public void onDestroy(){play.release();super.onDestroy();Toast.makeText(this, "销毁后台服务!", Toast.LENGTH_LONG).show();}

到此,我们放一个音乐在我们新建的raw文件夹中,这个raw文件夹也是存在res文件夹之下(和layout文件夹同级),要调用该文件内的内容时和调用layout里的XML文件一样,以下面的文件为例:R.raw.music0

七、代码

MainActivity.java

package com.mwt.mwtclass4th;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {private static final int SECONDACTIVITY = 1;private static final int THIRDACTIVITY = 2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overridepublic boolean onCreateOptionsMenu(Menu menu){getMenuInflater().inflate(R.menu.menu_main,menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {TextView label = (TextView) findViewById(R.id.label);EditText writein = (EditText) findViewById(R.id.shuru1);switch (item.getItemId()) {case R.id.main_menu_0:Intent intent = new Intent(MainActivity.this, NewActivity1.class);startActivityForResult(intent, SECONDACTIVITY);return true;case R.id.main_menu_1:Intent intent2 = new Intent(MainActivity.this, NewActivity2.class);startActivityForResult(intent2, THIRDACTIVITY);return true;case R.id.main_menu_2:Intent intent3 = new Intent(MainActivity.this, NewActivity3.class);String uriString = writein.getText().toString();Intent result = new Intent();result.putExtra("editText",uriString);result.setClass(MainActivity.this,NewActivity3.class);startActivity(result);//startActivityForResult(intent3, FORTHACTIVITY);return true;default:return false;}}
}

NewActivity1.java

package com.mwt.mwtclass4th;import androidx.appcompat.app.AppCompatActivity;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;public class NewActivity1 extends Activity {TextView textView1, textView2;Button button1, button2, returnmain;private String num = "";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_new1);returnmain = (Button) findViewById(R.id.reo);textView1 = (TextView) findViewById(R.id.textView1);textView2 = (TextView) findViewById(R.id.textView2);button1 = (Button) findViewById(R.id.button1);button2 = (Button) findViewById(R.id.button2);View.OnClickListener onClickListener = new View.OnClickListener() {@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubswitch (arg0.getId()) {case R.id.button1:num = "";for (int i = 0; i < 5; i++) //生成几个随机数{//num+=Math.random()*100+"\n";//生成的是100以内的小数num += Math.round(Math.random() * 100) + "\n";//生成100以内整数textView2.setText(num);}break;case R.id.button2:String fileName = "SdcardFile-" + System.currentTimeMillis() + ".txt";File dir = new File("/sdcard/");if (dir.exists() && dir.canWrite()) {File newFile = new File(dir.getAbsolutePath() + "/" + fileName);FileOutputStream fos = null;try {newFile.createNewFile();if (newFile.exists() && newFile.canWrite()) {fos = new FileOutputStream(newFile);fos.write(num.getBytes());textView1.setText(fileName + "文件写入SDcard");}} catch (Exception e) {// TODO: handle exceptione.printStackTrace();} finally {if (fos != null) {try {fos.flush();fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}break;default:break;}}};button1.setOnClickListener(onClickListener);button2.setOnClickListener(onClickListener);returnmain.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {setResult(RESULT_CANCELED, null);finish();}});}}

NewActivity2.java

package com.mwt.mwtclass4th;import androidx.appcompat.app.AppCompatActivity;import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;import org.xmlpull.v1.XmlPullParser;import java.io.IOException;
import java.io.InputStream;public class NewActivity2 extends Activity {Button reout;private ServiceForFile mathService;private boolean isBound = false;TextView labelView,labelView2,labelView3;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_new2);reout = (Button) findViewById(R.id.reout);labelView = (TextView)findViewById(R.id.label);labelView2 = (TextView)findViewById(R.id.label2);labelView3 = (TextView)findViewById(R.id.label3);Button bindButton = (Button)findViewById(R.id.bind);Button unbindButton = (Button)findViewById(R.id.unbind);Button computButton = (Button)findViewById(R.id.compute);reout.setOnClickListener(new View.OnClickListener(){public void onClick(View view){setResult(RESULT_CANCELED, null);finish();}});bindButton.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v) {if(!isBound){final Intent serviceIntent = new Intent(NewActivity2.this,ServiceForFile.class);bindService(serviceIntent,mConnection, Context.BIND_AUTO_CREATE);isBound = true;}}});unbindButton.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v) {if(isBound){isBound = false;unbindService(mConnection);mathService = null;}}});computButton.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v) {if (mathService == null){labelView.setText("未绑定服务");labelView2.setText(" ");labelView3.setText(" ");return;}long num = Math.round(Math.random() * 100) ;//生成100以内整数long num2 = Math.round(Math.random() * 100) ;long num3 = 0;if(num > num2 ){num3 =num;labelView.setText(num+"和"+num2+"相比,"+num3+"大。");}else if (num2 > num){num3 =num2;labelView.setText(num+"和"+num2+"相比,"+num3+"大。");}else if(num == num2)labelView.setText(num+"和"+num2+"相比,"+num+"和"+num2+"一样大。");}});}private ServiceConnection mConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {mathService = ((ServiceForFile.LocalBinder)service).getService();}@Overridepublic void onServiceDisconnected(ComponentName name) {mathService = null;}};
}

NewActivity3.java

package com.mwt.mwtclass4th;import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class NewActivity3 extends Activity {Intent intent;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_new3);Button button01 = (Button)findViewById(R.id.Button01);Button button02 = (Button)findViewById(R.id.Button02);Button button03 = (Button) findViewById(R.id.Button03);final TextView txt = (TextView)findViewById(R.id.TextView01);final TextView txt2 = (TextView)findViewById(R.id.TextView02);Intent intent1 = getIntent();String msg = intent1.getStringExtra("editText");txt2.setText(String.valueOf(msg));button03.setOnClickListener(new View.OnClickListener(){public void onClick(View view){setResult(RESULT_CANCELED, null);finish();}});Button.OnClickListener clicklistener=new View.OnClickListener() {public void onClick(View view) {switch  (view.getId()){case R.id.Button01:NewActivity3.this.startService(intent);txt.setText("start service .......");return;// textView.setText("Button按钮");return ;case R.id.Button02:NewActivity3.this.stopService(intent);return;}}};button01.setOnClickListener(clicklistener);button02.setOnClickListener(clicklistener);intent = new Intent(NewActivity3.this, ServiceForMusic.class);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.menu_music, menu);return true;}
}

ServiceForFile.java

package com.mwt.mwtclass4th;import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;public class ServiceForFile extends Service{private final IBinder mBinder = new LocalBinder();public class LocalBinder extends Binder {ServiceForFile getService() {return ServiceForFile.this;}}@Overridepublic IBinder onBind(Intent intent) {Toast.makeText(this, "本地绑定:MathService",Toast.LENGTH_SHORT).show();return mBinder;}@Overridepublic boolean onUnbind(Intent intent){Toast.makeText(this, "取消本地绑定:MathService",Toast.LENGTH_SHORT).show();return false;}
}

ServiceForMusic.java

package com.mwt.mwtclass4th;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.widget.Toast;public class ServiceForMusic extends Service {MediaPlayer play;@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}public void onCreate(){super.onCreate();play = MediaPlayer.create(this, R.raw.music0);Toast.makeText(this, "创建后台服务...", Toast.LENGTH_LONG).show();}public int onStartCommand(Intent intent, int flags, int startId){super.onStartCommand(intent, flags, startId);play.start();Toast.makeText(this, "启动后台服务程序,播放音乐...", Toast.LENGTH_LONG).show();return START_STICKY;}public void onDestroy(){play.release();super.onDestroy();Toast.makeText(this, "销毁后台服务!", Toast.LENGTH_LONG).show();}
}

menu_main.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/main_menu_0"android:title="SD卡存储"/><itemandroid:id="@+id/main_menu_1"android:title="启动信息获取服务"/><itemandroid:id="@+id/main_menu_2"android:title="音乐播放器"/></menu>

menu_music.xml

<menu xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:android="http://schemas.android.com/apk/res/android"><item android:id="@+id/menu_settings"android:title="@string/menu_settings"android:orderInCategory="100"app:showAsAction="never" />
</menu>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"package="com.mwt.mwtclass4th"><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"tools:ignore="ProtectedPermissions"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-sdk android:minSdkVersion="14" /><!-- 存储卡读写 -->
<!--    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />-->
<!--    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />--><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.Mwtclass4th"><serviceandroid:name=".ServiceForMusic"android:enabled="true"android:exported="true"></service><serviceandroid:name=".ServiceForFile"android:enabled="true"android:exported="true" /><activityandroid:name=".NewActivity3"android:exported="true"android:label="NewActivity3" /><activityandroid:name=".NewActivity2"android:exported="true"android:label="NewActivity2" /><activityandroid:name=".NewActivity1"android:exported="true"android:label="NewActivity1" /><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

八、演示




生成随机数并保存

如果没有绑定服务就点比较,会提示没绑定服务。

绑定提示

比较1

比较2

解绑

开启音乐

关闭音乐

九、流水账

这次相当于是一个当时上课的理论知识的大杂烩了,既用到了页面跳转 、Intent传值、menu菜单、inflate过滤器、后台服务、数据存储这些比较重点的内容,也用到了上课时只是随口一提的内容,比如说弹窗显示、基础性的for循环和if循环,总的来说比较考验对代码的熟练性。
音乐播放器内容是直接用的老师给的代码,即使是这样还是大概看了一遍,明白了它的代码原理;随机数生成参考的是下文参考中的第一个链接,其代码内容亲测可直接运行,想要把它改为我们题目所需要的内容只需要修改for循环的内容就好了。获取服务并比较大小的活动参考的是书上的随机数加法的代码,也不是很难,需要注意的可能就是在写代码的时候要看清楚代码块应该放在哪些类下面,不要乱放,有时候发现代码报错但是一直都改不了、越改越错,很可能就是因为代码一开始位置就放错而造成的。
这次是最后一次上机了,我的热情已经被磨没了,感觉时间都花在改bug和无效调试上面,有时候工程明明没错,但模拟器却出现了问题,让我有些无奈又有些无语。你能想到我每次运行模拟器之前都要清一次内存?每次都要等半天,等它重启完系统开机后我还得慢慢地等我的应用出来。它跟小程序只能说有点像,但实际上给我的感觉真的不一样,只能说安卓,有缘再见吧。

参考

Android:生成随机数,生成10个随机数,存入sdcard中的随机生成文件中
Android studio报错:app:mergeDebugResources FAILED(记一次痛苦不堪的debug)
Execution failed for task ':app:compileDebugJavaWithJavac’的小坑
安卓简易音乐播放器实现
android.permission.MOUNT_UNMOUNT_FILESYSTEMS添加权限报错
模拟器内图源网络,侵删。

移动终端应用开发上机4服务与数据存储相关推荐

  1. 如何设计云存储服务端数据存储加密机制

    云存储是一种新型的网络存储形式.随着云存储的广泛使用,云存储中的数据安全问题,如数据泄漏.数据篡改,如何设计云存储服务端数据存储加密机制也成了用户广泛关注的问题.云存储可以分为访问层.应用接口层.基础 ...

  2. 移动终端应用开发上机3组件通信与广播

    一.题目:设计一个APP. 1.设计一个APP. (1)APP中有两个界面. (2)主界面(MainActiivity)上有"登录"和"广播"两个按钮.点击&q ...

  3. 服务端mysql数据存储设计_服务端开发指南与最佳实战 | 数据存储技术 | MySQL(03) 如何设计索引...

    改善性能最好的方式,就是通过数据库中合理地使用索引,换句话说,索引是提高 MySQL 数据库查询性能的主要手段.在下面的章节中,介绍了索引类型.强制索引.全文索引. 基本索引类型 MySQL 索引可以 ...

  4. iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)

    ● 沙盒根目录:NSString *home = NSHomeDirectory(); ● Documents:(2种⽅方式) ● 利用沙盒根目录拼接"Documents"字符串 ...

  5. Android开发7:简单的数据存储(使用SharedPreferences)和文件操作

    前言 啦啦啦~大家好,又见面啦~ 本篇博文讲和大家一起完成一个需要注册.登录的备忘录的,一起学习 SharedPreferences 的基本使用,学习 Android 中常见的文件操作方法,复习 An ...

  6. iOS开发UI篇—ios应用数据存储方式(偏好设置)

    一.简单介绍 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能 每个应用都有个NSUserDefaults实例,通过它来存取偏 ...

  7. 【转】 [Unity3D]手机3D游戏开发:场景切换与数据存储(PlayerPrefs 类的介绍与使用)...

    http://blog.csdn.net/pleasecallmewhy/article/details/8543181 在Unity中的数据存储和iOS中字典的存储基本相同,是通过关键字实现数据存储 ...

  8. 董朝:打造云存储服务——移动端数据存储与分发

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:董朝,腾讯云存储业务终端负责人,2013年加入腾讯,主要负责手Q红点运营系统.会员.腾讯云云存储.移动开发平台的研发和优化工作.在移动 ...

  9. android app数据存储,基于Android开发的APP数据存储研究

    谢原武+龙文 摘要: 作为一个完整的应用程序,数据存储操作是必不可少的.Android系统一共提供了四种数据存储方式分别为File文件存储.Shared Preferences存储.ContentPr ...

最新文章

  1. mogileFS 分布式存储-安装手记
  2. 【C 语言】数组 ( 指针数组用法 | 命令行参数处理 )
  3. mysql数据库且字 语句是什么,MySQL(数据库)基本操作
  4. spring3.0 aop 获取 ibatis 执行的语句_Mybatis 源码分析:执行器
  5. python中print后面加逗号
  6. Python Flask Web 第七课 —— 使用 flask-moment 本地化日期和时间
  7. 远程采集Linux硬盘信息,关关采集器利用远程SFTP采集 Linux放主站+windows采集教程...
  8. html5 canvas实现led样式数字字体
  9. torchdiffeq中odeint函数的输入输出参数分析
  10. U盘拷贝时提示文件过大
  11. 如何获取a股level2数据接口?
  12. U8存货核算月末结账的月份跟日期对不上,导致无法结账
  13. Apache虚拟主机相关配置
  14. Pytorch 梯度计算,叶子节点,requires_grad,detach
  15. suspicious number
  16. Caused by: java.lang.NoSuchMethodError:No virtual method isSuccess()Z in class Lretrofit2/Response;
  17. 能源互联网中可再生能源发电建设的关键问题
  18. Python__字典
  19. Cadence PCB仿真使用Allegro PCB SI生成串扰细节报告Crosstalk Detailed Report及报告导读图文教程
  20. html mp3默认播放器,Win7系统下设置默认音乐播放器的两种方法

热门文章

  1. 云顶之弈机器人法爆_云顶之弈:6法机器人主C打法来了,一钩3400,3星效果最好!...
  2. 大数据技术之_23_Python核心基础学习_01_计算机基础知识 + Python 入门 (9.5小时)
  3. python双引号打不出来_在python 3中使用单引号和双引号时出错 - python
  4. FaceTime 即将推出降噪功能,但您现在就可以使用
  5. ps自由变化快捷键,取消选区。如何取消钢笔工具的选区
  6. 麒麟985和麒麟990哪个处理器好 麒麟985和麒麟990差距有多大
  7. 我,退休金8000,带孙子6年,退休前是大官,看到儿媳妇对我的称呼后,我直接怒了...
  8. 显示杂谈(9)-OLED挥之不去的痛之烧屏
  9. css左边定位,CSS Position(定位) | 菜鸟教程
  10. apollo学习笔记二:定位与感知