一般情况比如说有两个activity,分别叫A,B ,当在A里面激活B组件的时候, A 会调用 onPause()方法,然后B 调用onCreate() ,onStart(), OnResume() ,这个时候B覆盖了窗体, A会调用onStop()方法. 如果B呢 是个透明的,或者是对话框的样式, 就不会调用onStop()方法。
public class MusicPlayer implements MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {;
private MediaPlayer bgPlayer;
public MusicPlayer(Context context) {
this.context = context;
}
//当音乐播放完毕时
public void onCompletion(MediaPlayer mp) {
stopBgSound();
}
//当音乐播放发生错误时
public boolean onError(MediaPlayer mp, int what, int extra) {
stopBgSound();
return false;
}
//播放背景音乐,传入的paramInt为res/raw/目录下的音频文件的引用
public void playBgSound(int paramInt) {
stopBgSound();
try {
//利用音频文件创建一个MeidaPlayer
MediaPlayer mediaPlayer = MediaPlayer.create(context, paramInt);
bgPlayer = mediaPlayer;
bgPlayer.setOnCompletionListener(this);
//设置是否循环播放
bgPlayer.setLooping(true);
//开始播放
bgPlayer.start();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
//停止播放背景音乐
public void stopBgSound() {
if(bgPlayer == null)
return;
if(bgPlayer.isPlaying())
bgPlayer.stop();
bgPlayer.release();
bgPlayer = null;
}
}
然后,新建一个Activity,我命名为MyActivity :
public class MyActivity extends Activity {
public static MusicPlayer musicPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
if(musicPlayer == null) {
SysSetting.getInstance(getApplicationContext()).load();
musicPlayer = new MusicPlayer(getApplicationContext());
musicPlayer.playBgSound(R.raw.welcome);
}
}
}
在这里已经完成了大部分的工作,最后一步就是,让你所需要跨Activity播放背景音乐而不使用Service的Activity都继承与这个Activity就可以了。
什么是Service : Service,看名字就知道跟正常理解的“服务”差不多,后台运行,可交互这样的一个东西。它跟Activity的级别差不多,但是他 不能自己运行,需要通过某一个Activity或者其他Context对象来调用, Context.startService() 和 Context.bindService()。 两种启动Service的方式有所不同 : 如果在Service的onCreate或者onStart做一些很耗时间的事情,最好在 Service里启动一个线程来完成,因为Service是跑在主 线程中,会影响到UI操作或者阻塞主线程中的其他事情。 什么时候需要Service : 比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记 录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。 如何使用Service : Service的调用 Context.startService():Service会经历onCreate -> onStart(如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次 );stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。 注意,多次调用Context.startservice()不会嵌套(即使会有相应的onStart()方法被调用),所以无论同一个服务被启动了多少次,一旦调用Context.stopService()或者stopSelf(),他都会被停止。补充说明:传递给startService()的Intent对象会传递给onStart()方法。调用顺序为:onCreate --> onStart(可多次调用) --> onDestroy。 Context.bindService():Service会经历onCreate() -> onBind(),onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind -> onDestroyed相应退出,所谓绑定在一起就共存亡了 。 补充说明:传递给bindService()的Intent对象会传递给onBind(),传递给unbindService()的Intent对象会传递给onUnbind()方法。 调用顺序为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。 注意事项:在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。还有一点,目前我没有遇到过需要startService和bindService交互使用的情况(我认为不会有这种需求),所以不必去考虑交互的问题,待遇到时再考虑不迟。 adcastReceiver只能通过startService启动Service ,因为广播本身生命周期很短,bind的话没有意义 Service的生命周期 : Service的生命周期方法比Activity少一些,只有onCreate, onStart, onDestroy我们有两种方式启动一个Service,他们对Service 生命周期的影响是不一样的。 1 通过startService Service会经历 onCreate -> onStart stopService的时候直接onDestroy 如果是调用者(TestServiceHolder)自己直接退出而没有调用stopService的话,Service会一直在后台运行。 下次TestServiceHolder再起来可以stopService。 2 通过bindService Service只会运行onCreate, 这个时候 TestServiceHolder 和TestService绑定在一起 TestServiceHolder 退出了,Srevice就会调用onUnbind->onDestroyed所谓绑定在一起就共存亡了。 |
我们在使用HTC的GXX时,会发现他有一个功能是接通后振动提示,虽然说不是什么大的功能,但是使用比较方便,比如在呼叫过程中的时候就可以放在桌子上等振动了就说明电话被接通了再拿起来说话,就避免了一直放到耳边等待对方。具体的实现如下,当然实现方式可能和它不一样,但是效果一样,呵呵。由于我们是基于源码开发的,所以只讨论在PhoneApp里面添加该功能,独立模块或者基于SDK开发的不讨论。注意修改PhoneApp模块中的CallNotify.java文件。
1. 声明Vibrartor相关变量:
// Call active notify vibrate
private Vibrator mVibrator;
// Default vibrate time
private static final int VIBRATE_LENGTH = 100;
private boolean mAlreadyVibrate = true;
2. 在构造函数中创建Vibrator:
mVibrator = new Vibrator();
3. 在onPhoneStateChanged的末尾,也就是GSM分支中(只支持GSM call),加入如下代码段:
if(callState == Call.State.DISCONNECTING) {
mAlreadyVibrate = true;
}else if(mAlreadyVibrate &&
callState == Call.State.ACTIVE) {
// vibrate notify
mVibrator.vibrate(VIBRATE_LENGTH);
mAlreadyVibrate = false;
}
注:mAlreadyVibrate 主要是用于防止重复振动。OK,测试一下吧~
package com.test.telephone;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.TextView;
public class ActivityMain extends Activity {
private static final String TAG = "Telephony";
TextView view = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取电话管理的一个类实例
TelephonyManager mTelephonyMgr = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
// Registers a listener object to receive notification of changes in
// specified telephony states
// 建立一个监听器来实时监听电话的通话状态
mTelephonyMgr.listen(new TeleListener(),
PhoneStateListener.LISTEN_CALL_STATE);
view = new TextView(this);
view.setText("listen the state of phone/n");
setContentView(view);
}
class TeleListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
// 当处于待机状态中
case TelephonyManager.CALL_STATE_IDLE: {
Log.e(TAG, "CALL_STATE_IDLE");
view.append("CALL_STATE_IDLE " + "/n");
break;
}
// 当处于通话中
case TelephonyManager.CALL_STATE_OFFHOOK: {
Log.e(TAG, "CALL_STATE_OFFHOOK");
view.append("CALL_STATE_OFFHOOK" + "/n");
break;
}
// 当处于拨号状态中..
case TelephonyManager.CALL_STATE_RINGING: {
Log.e(TAG, "CALL_STATE_RINGING");
view.append("CALL_STATE_RINGING" + "/n");
break;
}
default:
break;
}
}
}
}
一般就是动态加载,仅在需要加载的时候加载数据项。
比如View只能显示10项,当滚动到第10项时,我们才加载后面的N(N根据实际情况判定)项。这就需要监听滚动消息,很好,ListView有这个回调(onScroll和onScrollStateChanged),我们结合这二个重载的函数,检查当滚动状态改变,即滚动到底部时,我们就加载这N项。
很多应用都是采用分批次加载的形式来获取用户所需的数据。比如:微博客户端可能会在用户滑动至列表底端时自动加载下一页数据,也可能在底部放置一个“加载更多”按钮,用户点击后,加载下一页数据。
对于问题2:已加载很多数据项的ListView如何优化效率
一般ListView数据量大时,效率地下的瓶颈在getView函数中,我们需要优化,就是尽可能的减少重复的,无意义的操作。
普遍的做法都是将当前显示的view绑定一个结构题,下次我们只要获取这个结构题就OK了。
具体用法,见参考文章2:
7.移动应用开发“三不要”
不要让我等 不要让我想 不要让我烦
是因为启动程序(主界面也是一个app),发现了在这个程序中存在一个设置为
所以这个launcher会把icon提出来,放在主界面上。当用户点击icon的时候,发出一个Intent:
Intent intent = mActivity.getPackageManager().getLaunchIntentForPackage(packageName);
mActivity.startActivity(intent);
跳过去可以跳到任意允许的页面,如一个程序可以下载,那么真正下载的页面可能不是首页(也有可能是首页),这时还是构造一个Intent,startActivity.
这个intent中的action可能有多种view,download都有可能。系统会根据第三方程序向系统注册的功能,为你的Intent选择可以打开的程序或者页面。所以唯一的一点
不同的是从icon的点击启动的intent的action是相对单一的,从程序中跳转或者启动可能样式更多一些。本质是相同的。
不建议:
服务
广播