Android面试知识(2)

14、页面上现有ProgressBar控件progressBar,请用手写线程以10秒的的时间完成其进度显示工作。

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;

public class ProgressBarTestActivity extends Activity {
    private ProgressBar mProgress;
    private Handler mHandler = new Handler();

    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.progressbar_activity);
        mProgress = (ProgressBar) findViewById(R.id.progress_bar);
        Thread thread = new Thread(new Runnable() {
            public void run() {
                int progressBarMax = mProgress.getMax();
                try {
                    while (progressBarMax != mProgress.getProgress()) {
                        int stepProgress = progressBarMax / 10;
                        int currentprogress = mProgress.getProgress();
                        final int progress = stepProgress + currentprogress;
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mProgress.setProgress(progress);
                            }
                        });
                        Thread.sleep(1000);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }
}

15、请描述下Activity的生命周期

必调用的三个方法:onCreate() –> onStart() –> onResume(),用AAA表示。
- 父Activity(A)启动,点击启动子Activity(B),子Actvity退出,返回父Activity的调用顺序如下:
AAA –> onFreeze() –> onPause() –> B onCreate() -> B onStart() -> B onResume –> onStop() –> onRestart() –> onStart()->onResume()
- 用户点击Home,Actvity调用顺序如下:
AAA –> onFreeze() -> onPause() –> onStop() — Maybe –> onDestroy()
- 用户点击back键,Activity调用顺序如下:
AAA-> onPause() –> onStop() –> onDestroy() ->onCreate()->onStart()->onResume()
- 在Activity上显示dialog, Activity调用顺序如下:
AAA -> onPause()
- 在父Activity上显示透明的或非全屏的activity,Activity调用顺序如下:
AAA –> onFreeze() –> onPause()
- 设备进入睡眠状态,Activity调用顺序如下:
AAA –> onFreeze() –> onPause()

16、如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态?

onSaveInstanceState()
当你的程序中某一个Activity A在运行时,主动或被动地运行另一个新的Activity B,这个时候A会执行onSaveInstanceState(),如下:

public void onSaveInstanceState(Bundle outState) {    
    super.onSaveInstanceState(outState);    
    outState.putLong("id", 1234567890);
} 

B完成以后又回来找A,这个时候就有两种情况:一是A被回收,二是A没有被回收,被回收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上了参数savedInstanceState;而没被收回的就直接执行onResume(),跳过onCreate()了。

17、如何将一个Activity设置成窗口的样式。

在AndroidManifest.xml 中定义Activity的地方加上主题android:theme=”@android:style/Theme.Dialog”或android:theme=”@android:style/Theme.Translucent”就变成半透明的

18、如何退出Activity?如何安全退出已调用多个Activity的Application?

  • 退出Activity直接调用Activity的finish()方法。
  • 退出多个Activity应用:
    方法一记录打开的Activity,每打开一个Activity,就记录下来,在需要退出时,关闭每一个activity;
    方法二发送特定的广播,在需要结束应用时,发送一个特定的广播,每一个Activity收到广播后关闭;
    方法三通过Intent的flag来实现,实现intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)激活一个新的 activity。此时如果该任务栈中已经有该 Activity,那么系统会把这个Activity上面的所有Activity干掉。其实相当于给Activity配置的启动模式为SingleTask。

19、请介绍下ContentProvider是如何实现数据共享的。

Android提供了ContentProvider,一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProviders是以类似数据库中表的方式将数据暴露,也就是说ContentProvider就像一个“数据库”。那么外界获取其提供的数据,也就应该与从数据库中获取数据的操作基本一样,只不过是采用URI来表示外界需要访问的“数据库”。外部访问通过ContentResolver去访问并操作这些被暴露的数据。所以,创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中(前提是有相同数据类型并且有写入Content provider的权限),就可实现共享。

20、如何启用Service,如何停用Service。

1)、步骤

第一步:继承Service类:

public class SMSService extends Service {}

第二步:在AndroidManifest.xml文件中的节点里对服务进行配置:

<service android:name=".SMSService"/>
2)、Context.startService()和Context.bindService()

服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。
- 使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。

  • 使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。

  • 如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。

  • 如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()–>onDestroy()方法。

3)、Service的生命周期
  • onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。onDestroy()该方法在服务被终止时调用。

    与采用Context.startService()方法启动服务有关的生命周期方法:
    
  • onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用

    与采用Context.bindService()方法启动服务有关的生命周期方法:
    
  • onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用

  • onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用

21、注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意。

在android下,要想接受广播信息,就需要自己来实现一个广播接收器,这里重写onReceiver()方法,来实现一个信息防火墙:

public class SmsBroadCastReceiverextendsBroadcastReceiver {  
   @Override  
   public void onReceive(Context context, Intentintent) {   
       Bundle bundle = intent.getExtras();  
       Object[] object = (Object[])bundle.get("pdus");   
       SmsMessage sms[] = new SmsMessage[object.length];   
       for(int i = 0;i < object.length;i++) {   
            sms[0] = SmsMessage.createFromPdu((byte[])object);  
            Toast.makeText(context,"来自" + sms.getDisplayOriginatingAddress()+"的消息是:" + sms.getDisplayMessageBody(),Toast.LENGTH_SHORT).show();   
       }   
       //终止广播,在这里我们可以稍微处理,根据用户输入的号码可以实现短信防火墙。   
       abortBroadcast();   
   }   
} 

当实现了广播接收器,还要设置广播接收器接收广播信息的类型,这里是信息:android.provider.Telephony.SMS_RECEIVED

我们就可以把广播接收器注册到系统里面,可以让系统知道我们有个广播接收器。这里有两种,一种是代码动态注册

//生成广播处理  
smsBroadCastReceiver = new SmsBroadCastReceiver();   
//实例化过滤器并设置要过滤的广播  
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
//注册广播   
BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver,intentFilter); 

一种是在AndroidManifest.xml中配置广播:

<?xmlversion="1.0"encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
     package="spl.broadCastReceiver"  
     android:versionCode="1" 
     android:versionName="1.0"> 
   <application android:icon="@drawable/icon"android:label="@string/app_name">
       <activity android:name=".BroadCastReceiverActivity"  
                  android:label="@string/app_name">  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN"/>  
                <category android:name="android.intent.category.LAUNCHER"/>  
            </intent-filter>  
       </activity>  

       <!--广播注册-->  
       <receiver android:name=".SmsBroadCastReceiver">  
            <intent-filter android:priority="20">  
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>  
            </intent-filter>  
       </receiver>  

   </application>  

   <uses-sdk android:minSdkVersion="7"/>  

   <!-- 权限申请 -->  
   <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>  

</manifest>   

两种注册类型的区别是:

1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。

2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值