美文网首页
Activity之间那些事你都知道了么

Activity之间那些事你都知道了么

作者: Dapengyou | 来源:发表于2019-02-12 01:25 被阅读3次
    学习刚要

    Activity是与用户交互的接口
    Android系统是通过Activity栈的形式来管理Activity

    下面我将会从以下几个方面对Activity进行总结:

    • Activity的四种展示形态
    • Activity的启动模式
    • Activity的生命周期
    • Activity组件之间的通信

    Activity四种形态

    1. Active(Activity处于栈顶)
    2. Paused (可见但不可交互,只是失去和用交互的能力)
    3. Stopped (不可见,被另一个Activity完全覆盖,在内存足够时,数据、状态、变量都被保存,内存不足时,数据、状态、变量被系统回收掉)
    4. killed (系统回收掉)

    Activity启动模式

    1. Standard
      系统默认的启动模式,Activity可多次被实例化,一个任务栈中会有多个实例。
      应用场景:系统默认

    2. SingleTop
      SingleTop分两种情况:一种情况是Activity位于栈顶,另一种是Activity不在栈顶时,但存在于栈中。

      • 当Activity在栈顶时,启用Activity,不会创建新的实例,并重用栈顶的Activity,通过onNewIntent()将Intent对象传入这个实例中。
      • 当Activity不在栈顶时,但存在于栈中,会启用与standard相同的模式

      应用场景:IM对话框,新闻客户端推送

    3. SingleTask
      首先会根据taskAffinity(任务相关性)去寻找当前是否存在一个对应名字的任务栈,如果不存在,则建一个新的task放于栈顶,如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例,若存在,系统会销毁在Activity上的所有的Activity,最终使Activity置于栈顶,再回调onNewIntent()函数

      应用场景:应用的主界面

    4. SingleInstance
      Activity会在一个独立的任务中启动,并且在这个栈中只有这一个实例,而被该实例启动的其他Activity会自动运行在另一个任务中,再次启动时该实例会重用已存在的任务和实例,在AndroidManifest文件中的lauchMode属性中设置。

      特性:

      • 以SingleInstance模式启动的Activity具有全局唯一性
      • 以SingleInstance模式启动的Activity具有独占性

      应用场景:呼叫来电

    Activity生命周期

    Activity正常情况下的周期调用

    Activity的生命周期就是Activity从创建到销毁的一个过程,仿佛我们人从出生到死亡一样。

    Activity生命周期的方法:
    • onCreate();创建
    • onStart();运行
    • onResume();获取焦点
    • onPause();失去焦点
    • onStop();暂停
    • onDestroy();销毁
    • onRestart();重运行
    一个Activity的多种变化形式:
    • 从无到有创建一个Activity
    • 当前的Activity失去焦点
    • 从当前的Activity跳转到另一个Activity
    • 当前Activity被置入后台

    从创建一个Activity到销毁的生命周期:

    1. 一个Activity刚创建时候的生命周期:

    onCreate() ——> onStart() ——> onResume()

    1. Activity从创建到销毁的生命周期:

    onCreate() ——> onStart() ——> onResume() ——>onPause() ——> onStop() ——> onDestroy()

    1. Activity从启动到失去焦点生命周期:

    onCreate() ——> onStart() ——> onResume() ——> onPause()

    1. Activity从启动到失去焦点,再到获取焦点的生命周期:

    onCreate() ——> onStart() ——> onResume() ——> onPause() ——> onResume()

    1. Activity从启动到后台的生命周期:

    onCreate() ——> onStart() ——> onResume() ——> onPause() ——>onStop()

    1. Activity从启动到后台,再到前台的生命周期:

    onCreate() ——> onStart() ——> onResume() ——> onPause() ——> onStop() ——> onRestart() ——> onStart() ——>onResume()

    Activity异常情况下的周期调用

    异常情况下多了两个方法:onSaveInstanceState(),onRestoreInstanceState(),这两个方法是出现异常情况下系统自动调用的,通常 onSaveInstanceState() 只适合用于保存一些临时性的状态,而 onPause() 适合用于数据的持久化保存。当Activity被重新创建后,系统会调用 onRestoreInstanceState() 方法,此方法会将Activity销毁时通过 onSaveInstanceState() 保存的bundle对象作为一个对象传给 onRestoreInstanceState() 方法,同时也会传递给 onCreate() 方法。

    onRestoreInstanceState() 方法与 onCreate() 方法都可以进行数据恢复,他两区别在于:onRestoreInstanceState()传入的参数一定不能为空,onCreate() 传入的参数有可能为空,所以使用onRestoreInstanceState() 进行数据恢复比较好。

    onRestoreInstanceState() 方法在 onStart() 之后执行,onSaveInstanceState() 方法在 onPause() 之后执行。

    下面看个横竖屏切换的小例子观察下onRestoreInstanceState()方法的调用

    public class ReviewActivity extends AppCompatActivity {
        private final String TAG = ReviewActivity.class.getSimpleName();
        private static final String TURN = "turn";
        @BindView(R.id.et_name)
        EditText mEtName;
        @BindView(R.id.tv_show)
        TextView mTvShow;
    
        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            Log.d(TAG, "onRestoreInstanceState: " + "调用onRestoreInstanceState");
            super.onRestoreInstanceState(savedInstanceState);
            mTvShow.setText(savedInstanceState.getString(TURN));
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            Log.d(TAG, "onCreate: 调用onCreate");
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_review);
            
            ButterKnife.bind(this);
        }
    
        @Override
        protected void onStart() {
            Log.d(TAG, "onStart: 调用onStart");
            super.onStart();
        }
    
        @Override
        protected void onResume() {
            Log.d(TAG, "onResume: 调用onResume");
            super.onResume();
        }
    
        @Override
        protected void onRestart() {
            Log.d(TAG, "onRestart: 调用onRestart");
            super.onRestart();
        }
    
        @Override
        protected void onPause() {
            Log.d(TAG, "onPause: 调用onPause");
            super.onPause();
        }
    
        @Override
        protected void onStop() {
            Log.d(TAG, "onStop: 调用onStop");
            super.onStop();
        }
    
        @Override
        protected void onDestroy() {
            Log.d(TAG, "onDestroy: 调用onDestroy");
            super.onDestroy();
        }
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            Log.d(TAG, "onSaveInstanceState: 调用onSaveInstanceState");
            super.onSaveInstanceState(outState);
            outState.putString(TURN, mEtName.getText().toString());
    
        }
    
        @OnClick(R.id.bt_sure)
        public void onViewClicked() {
            mTvShow.setText(mEtName.getText().toString());
        }
    
    }
    

    运行后的效果:

    操作细节 结果展示

    最后防止重新创建activity:
    可以在AndroidManifest.xml中指定configChange属性来不让系统重新创建

     <activity
                android:name=".activity.ReviewActivity"
                android:configChanges="orientation|screenSize" />
    
      /**
         * @param newConfig :
         * @return : void
         * @date 创建时间: 2018/12/1
         * @author lady_zhou
         * @Description  activity不被重建
         */
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            Log.d(TAG, "onConfigurationChanged: 切屏防止activity调用onSaveInstanceState");
            super.onConfigurationChanged(newConfig);
        }
    
    操作细节 结果展示
    Activity与Fragment生命周期关系

    从创建一个含有Fragment的Activity到 销毁的生命周期:

    Fragment生命周期的方法:
    • onAttach();fragment已经关联到activity,只调用一次
    • onCreate();系统创建fragment的时候回调他,只调用一次
    • onCreateView();绘制layout
    • onActivityCreated();当Activity中的onCreate方法执行完后调用。
    • onStart();运行
    • onResume();获取焦点
    • onPause();失去焦点
    • onStop();暂停
    • onDestroyView();Fragment中的布局被移除时调用
    • onDestroy();销毁
    • onDetach();Fragment和Activity解除关联的时候调用
    与Activity一样Fragment也有的多种变化形式:
    • 从无到有创建一个Fragment
    • 当前Activity被置入后台
    1. 刚创建时候的生命周期:

    Activity中onCreate()——>Activity中onStart()——>Fragment中onAttach()——>Fragment中onCreate()——>Fragment中onCreateView()——>Fragment中onActivityCreated()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()

    1. 从创建到销毁的生命周期:

    Activity中onCreate()——>Activity中onStart()——>Fragment中onAttach()——>Fragment中onCreate()——>Fragment中onCreateView()——>Fragment中onActivityCreated()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()——>Activity中onPause()——>Fragment中onPause()——>Activity中onStop()——>Fragment中onStop()——>Activity中onDestroy()——>Fragment中onDestroyView()——>Fragment中onDestroy()——>Fragment中onDetach()

    1. 从启动到后台的生命周期:

    Activity中onCreate()——>Activity中onStart()——>Fragment中onAttach()——>Fragment中onCreate()——>Fragment中onCreateView()——>Fragment中onActivityCreated()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()——>Activity中onPause()——>Fragment中onPause()——>Activity中onSaveInstanceState()——>Activity中onStop()——>Fragment中onStop()

    1. 从启动到后台,再到前台的生命周期:

    Activity中onCreate()——>Activity中onStart()——>Fragment中onAttach()——>Fragment中onCreate()——>Fragment中onCreateView()——>Fragment中onActivityCreated()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()——>Activity中onPause()——>Fragment中onPause()——>Activity中onSaveInstanceState()——>Activity中onStop()——>Fragment中onStop()——>Activity中onRestart()——>Activity中onStart()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()

    public class ActivityToFragmentActivity extends AppCompatActivity implements MyFragment.FragmentCallBack {
        private static final String TAG = "Fragment";
        @BindView(R.id.tv_back)
        TextView mTvBack;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            Log.d(TAG, "Activity: 调用onCreate");
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_to_fragment);
            ButterKnife.bind(this);
    
            FragmentManager fragmentManager = getSupportFragmentManager();
    
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
            MyFragment mFragment = new MyFragment();
    
            fragmentTransaction.replace(R.id.fragment, mFragment);
            fragmentTransaction.commit();
    
        }
    
        @Override
        protected void onStart() {
            Log.d(TAG, "Activity: 调用onStart");
            super.onStart();
        }
    
        @Override
        protected void onResume() {
            Log.d(TAG, "Activity: 调用onResume");
            super.onResume();
        }
    
        @Override
        protected void onRestart() {
            Log.d(TAG, "Activity: 调用onRestart");
            super.onRestart();
        }
    
        @Override
        protected void onPause() {
            Log.d(TAG, "Activity: 调用onPause");
            super.onPause();
        }
    
        @Override
        protected void onStop() {
            Log.d(TAG, "Activity: 调用onStop");
            super.onStop();
        }
    
        @Override
        protected void onDestroy() {
            Log.d(TAG, "Activity: 调用onDestroy");
            super.onDestroy();
        }
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            Log.d(TAG, "Activity: 调用onSaveInstanceState");
            super.onSaveInstanceState(outState);
        }
    
        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            Log.d(TAG, "Activity: " + "调用onRestoreInstanceState");
            super.onRestoreInstanceState(savedInstanceState);
        }
    }
    

    Fragment

    public class MyFragment extends Fragment {
        private static final String TAG = "Fragment";
        @BindView(R.id.tv_text)
        TextView mTvText;
        Unbinder unbinder;
    
        @Override
        public void onAttach(Context context) {
            Log.d(TAG, "Fragment: 调用onAttach");
            super.onAttach(context);
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            Log.d(TAG, "Fragment: 调用onCreate");
            super.onCreate(savedInstanceState);
        }
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            Log.d(TAG, "Fragment: 调用onCreateView");
            View view = inflater.inflate(R.layout.activity_fragment, container, false);
    
            unbinder = ButterKnife.bind(this, view);
    
            return view;
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            Log.d(TAG, "Fragment: 调用 onActivityCreated");
            super.onActivityCreated(savedInstanceState);
        }
    
        @Override
        public void onStart() {
            Log.d(TAG, "Fragment: 调用 onStart");
            super.onStart();
        }
    
        @Override
        public void onResume() {
            Log.d(TAG, "Fragment: 调用 onResume");
            super.onResume();
        }
    
        @Override
        public void onPause() {
            Log.d(TAG, "Fragment: 调用 onPause");
            super.onPause();
        }
    
        @Override
        public void onStop() {
            Log.d(TAG, "Fragment: 调用 onStop");
            super.onStop();
        }
    
        @Override
        public void onDestroyView() {
            Log.d(TAG, "Fragment: 调用 onDestroyView");
            super.onDestroyView();
            unbinder.unbind();
        }
    
        @Override
        public void onDestroy() {
            Log.d(TAG, "Fragment: 调用 onDestroy");
            super.onDestroy();
        }
    
     
        @Override
        public void onDetach() {
            Log.d(TAG, "Fragment: 调用 onDetach");
            super.onDetach();
        }
    }
    
    操作细节

    Activity组件之间的通信

    我将Activity组件之间的通信分为以下三种:

    1. Activity与Activity之间通信
    2. Activity与Fragment之间通信
    3. Activity与Service数据通信
    
    Activity与Activity之间通信

    Activity与Activity之间通信主要有以下几种方式

    1. Intent/Bundle
    2. 类静态变量
    3. 全局变量
    4. EventBus
    

    这里主要是介绍第一种方式:Intent/Bundle
    第一个Activity

    public class OneActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_one);
            ButterKnife.bind(this);
    
        }
    
        @OnClick(R.id.bt_to_activity)
        public void onViewClicked() {
            Bundle bundle = new Bundle();
            bundle.putInt("age", 19);
            bundle.putString("name", "雷东宝");
    
            Intent intent = new Intent(OneActivity.this, SecondActivity.class);
            intent.putExtras(bundle);
            startActivity(intent);
        }
    }
    

    第二个Activity,显示从第一个Activity中传入的名字和年龄

    public class SecondActivity extends AppCompatActivity {
    
        @BindView(R.id.tv_name)
        TextView mTvName;
        @BindView(R.id.tv_age)
        TextView mTvAge;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_second);
            ButterKnife.bind(this);
    
            //用getIntent()方法获取intent
            Intent intent = getIntent();
            String name = intent.getStringExtra("name");
            int age = intent.getIntExtra("age", 0);
    
            mTvName.setText("传来的名字是:\t" + name);
            mTvAge.setText("传来的年龄是:\t" + age);
        }
    }
    
    
    操作细节
    Activity与Fragment之间通信

    其中Activity与Fragment之间通信又可以分为

    • Activity传递数据给Fragment
    • Fragment传递数据给Activity

    Fragment 与 Activity 通信存在三种情形:

    1. Activity 操作内嵌的 Fragment,
    2. Fragment 操作宿主 Activity,
    3. Fragment 操作同属 Activity中的其他 Fragment。
    

    下面的demo主要是基于前两种情形

    Activity传递数据给Fragment的方法我总结为两点:

    1. 使用Bundle
    2. 直接在Activity中定义方法
    

    我这里主要介绍使用Bundle方法
    步骤在代码里已经注释清楚了
    Fragment

    public class MyFragment extends Fragment {
        private static final String TAG = "Fragment";
        @BindView(R.id.tv_text)
        TextView mTvText;
        Unbinder unbinder;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            Log.d(TAG, "Fragment: 调用onCreateView");
            View view = inflater.inflate(R.layout.activity_fragment, container, false);
    
            unbinder = ButterKnife.bind(this, view);
    
            if(isAdded()) {//判断Fragment已经依附Activity
                //收到Activity传来的值第一步 获取从Activity中传过来的全部值
                savedInstanceState = this.getArguments();
                //收到Activity传来的值第二步  获取某一个值
                if (savedInstanceState != null) {
                    String message = savedInstanceState.getString("message");
                    mTvText.setText("我是fragment\n Activity传过来的值:" + message);
                }
            }
    
            return view;
        }
    }
    

    对应的Activity

    public class ActivityToFragmentActivity extends AppCompatActivity  {
        private static final String TAG = "Fragment";
        @BindView(R.id.tv_back)
        TextView mTvBack;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            Log.d(TAG, "Activity: 调用onCreate");
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_to_fragment);
            ButterKnife.bind(this);
    
            //第一步获取FragmentManager
            FragmentManager fragmentManager = getSupportFragmentManager();
    
            //第二步获取FragmentTransaction
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
            //第三步创建需要添加的Fragment
            MyFragment mFragment = new MyFragment();
    
            //第四步创建Bundle对象
            Bundle bundle = new Bundle();
    
            //第五步往bundle中添加数据
            bundle.putString("message", "Activity往Fragment中传值");
    
            //第六步  将数据添加在fragment中
            mFragment.setArguments(bundle);
    
            //第七步  动态添加fragment
            fragmentTransaction.replace(R.id.fragment, mFragment);
            fragmentTransaction.commit();
    
        }
    }
    

    Fragment传递数据给Activity的方法也有很多:

    1. Handler
    2. 广播
    3. EventBus
    4. 接口回调
    5. Bundle和setArguments(bundle)
    

    我这里主要介绍Fragment传递数据给Activity的方法中的接口回调

    实现Fragment传递数据给Activity的接口回调主要分四步:
    第一步: 定义回调接口
    第二步: 定义接口属性
    第三步: 获取相应的Activity
    第四步: 调用接口中的方法

    下面是Fragment中的代码:

    public class MyFragment extends Fragment {
        private static final String TAG = "Fragment";
        @BindView(R.id.tv_text)
        TextView mTvText;
        Unbinder unbinder;
    
        //回传Activity第二步  定义属性
        private FragmentCallBack mFragmentCallBack;
    
        @Override
        public void onAttach(Context context) {
            Log.d(TAG, "Fragment: 调用onAttach");
            super.onAttach(context);
            if (context instanceof FragmentCallBack) {
                mFragmentCallBack = (FragmentCallBack) context;//回传Activity第三步  获取相应的Activity
            } else {
                throw new IllegalArgumentException("接口必须是FragmentCallBack");
            }
        }
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            Log.d(TAG, "Fragment: 调用onCreateView");
            View view = inflater.inflate(R.layout.activity_fragment, container, false);
    
            unbinder = ButterKnife.bind(this, view);
            return view;
        }
    
     @Override
        public void onDestroyView() {
            Log.d(TAG, "Fragment: 调用 onDestroyView");
            super.onDestroyView();
            unbinder.unbind();
        }
        /**
         * @return : void
         * @date 创建时间: 2019/1/16
         * @author lady_zhou
         * @Description 将传递进来的Activity对象释放掉
         */
        @Override
        public void onDetach() {
            Log.d(TAG, "Fragment: 调用 onDetach");
            super.onDetach();
            mFragmentCallBack = null;
        }
    
        @OnClick(R.id.bt_button)
        public void onViewClicked(View view) {
                    mFragmentCallBack.sendContent("从Fragment中回传回来的值");//回传Activity第四步  调用接口中的方法
            }
        }
    
        /**
         * @author lady_zhou
         * @createTime: 2019/2/6
         * @Description 回传Activity第一步  定义回调接口
         */
        public interface FragmentCallBack {
            void sendContent(String info);
        }
    

    对应的Activity的代码:

    public class ActivityToFragmentActivity extends AppCompatActivity implements MyFragment.FragmentCallBack {
        private static final String TAG = "Fragment";
        @BindView(R.id.tv_back)
        TextView mTvBack;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            Log.d(TAG, "Activity: 调用onCreate");
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_to_fragment);
            ButterKnife.bind(this);
    
            //获取FragmentManager
            FragmentManager fragmentManager = getSupportFragmentManager();
    
            //获取FragmentTransaction
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
            //创建需要添加的Fragment
            MyFragment mFragment = new MyFragment();
    
            // 动态添加fragment
            fragmentTransaction.replace(R.id.fragment, mFragment);
            fragmentTransaction.commit();
    
        }
    
        /**
         * @param info :  Activity返回的值
         * @return : void
         * @date 创建时间: 2019/2/6
         * @author lady_zhou
         * @Description 实现回调接口
         */
        @Override
        public void sendContent(String info) {
            if (info != null) {
                mTvBack.setText("这是Activity\n从Fragment返回的值是:" + info);
            }
        }
    
    操作细节
    Activity与Service数据通信

    Activity与Service数据通信主要有以下几个方法:

    1. 绑定服务,利用ServiceConnection类(在Activity中实现这个类,同时实现onServiceConnected() 和onServiceDisconnected() 方法)
    2. 简单通信,利用Intent进行传值
    3. 定义一个回调接口来监听服务中的进程的变化使用handle切换到主线程
    

    下面的下载小demo使用第一种和第三种方法,主要实现构想是:
    点击下载后,进度条显示当前下载的进度(没有使用网络,只是个小demo),代码很简单应该很容易看懂
    Activity中的代码

    public class ActivityToServiceActivity extends AppCompatActivity {
        private final String TAG = getClass().getSimpleName();
        private static final String KEY = "data";
    
        @BindView(R.id.bt_download)
        Button mBtDownload;
        @BindView(R.id.progressbar)
        ProgressBar mProgressbar;
        @BindView(R.id.tv_text)
        TextView mTvText;
    
        //绑定服务第一步:  先创建服务中的binder对象
        private DownLoadService mDownLoadService = null;
        private Intent mIntent;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_to_service);
            ButterKnife.bind(this);
    
            mIntent = new Intent(ActivityToServiceActivity.this, DownLoadService.class);
        }
    
        @OnClick(R.id.bt_download)
        public void onViewClicked() {
            bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);//绑定服务
        }
    
        ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                //绑定服务第二步:  获取到DownLoadService返回的binder对象,并开启服务
                mDownLoadService = ((DownLoadService.MyBinder) service).startService();
    
                //注册回调接口来接收下载进度的变化
                mDownLoadService.setOnProgressListener(new DownLoadService.OnProgressListener() {
    
                    @Override
                    public void onProgress(int progress) {
                        mProgressbar.setProgress(progress);
    
                        //使用Handle
                        Message message = new Message();
                        Bundle bundle = new Bundle();
                        bundle.putInt(KEY, progress);
                        message.setData(bundle);
                        mHandler.sendMessage(message);
    
                        if (progress == 100) {
                            unbindService(mServiceConnection);
                            mDownLoadService = null;
                            Log.d(TAG, "方法:onProgress: \t\t解绑服务");
                        }
                        Log.d(TAG, "方法:onProgress: \t\t" + progress);
    
                    }
                });
    
    
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };
    
        private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //切换到主线程显示进度
                mTvText.setText(msg.getData().getInt(KEY,0)+"%");
                if(msg.getData().getInt(KEY,0)==100){
                    Toast.makeText(ActivityToServiceActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
                }
            }
        };
    
        @Override
        protected void onDestroy() {
            if (mDownLoadService != null) {
                unbindService(mServiceConnection);
            }
            super.onDestroy();
        }
    }
    

    下载服务实现:

    public class DownLoadService extends Service {
        private final String TAG = getClass().getSimpleName();
        //进度条的最大值
        public static final int MAX_PROGRESS = 100;
    
        // 进度条的进度值
        private int progress = 0;
    
        private OnProgressListener onProgressListener;
        private Thread mThread;
    
        /**
         * @param intent :  返回一个Binder对象
         * @return : android.os.IBinder
         * @date 创建时间: 2019/1/16
         * @author lady_zhou
         * @Description
         */
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            startDownLoad();
            return new MyBinder();
        }
    
        public class MyBinder extends Binder {
            /**
             * 获取当前Service的实例
             *
             * @return
             */
            public DownLoadService startService() {
                return DownLoadService.this;
            }
        }
    
        /**
         * @return : void
         * @date 创建时间: 2019/1/16
         * @author lady_zhou
         * @Description 模拟下载任务,每秒钟更新一次
         */
        public void startDownLoad() {
            mThread = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (progress < MAX_PROGRESS) {
                        progress += 10;
                        //中断线程
                        if (Thread.currentThread().isInterrupted()) {
                            Log.d(TAG, "方法:run: \t\t中断线程");
                            break;
                        }
                        //进度发生变化通知调用方
                        if (onProgressListener != null) {
                            onProgressListener.onProgress(progress);
                        }
    
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
    
                        Log.d(TAG, "方法:run: 线程\t\t" + progress);
                    }
                }
            });
            mThread.start();
        }
    
        /**
         * @author lady_zhou
         * @createTime: 2019/1/16
         * @Description 更新进度的回调接口
         */
        public interface OnProgressListener {
            void onProgress(int progress);
        }
    
        /**
         * @param onProgressListener :
         * @return : void
         * @date 创建时间: 2019/1/16
         * @author lady_zhou
         * @Description 注册回调接口的方法,供外部调用
         */
        public void setOnProgressListener(OnProgressListener onProgressListener) {
            this.onProgressListener = onProgressListener;
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            Log.d(TAG, "方法:onUnbind: \t\t解绑了");
            mThread.interrupt();//中断线程
    
            return super.onUnbind(intent);
        }
    }
    
    操作细节

    以上代码的github链接

    相关文章

      网友评论

          本文标题:Activity之间那些事你都知道了么

          本文链接:https://www.haomeiwen.com/subject/rvtmcqtx.html