Android常用组件

Toast

这是个常用的进行消息提示组件。

void midToast(String str, int showTime)
{
    Toast toast = Toast.makeText(global_context, str, showTime);            
    toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL , 0, 0);  //设置显示位置
    TextView v = (TextView) toast.getView().findViewById(android.R.id.message);
    v.setTextColor(Color.YELLOW);     //设置字体颜色
    toast.show();   
}

AlertDialog(对话框)基本运用

public class MainActivity extends AppCompatActivity {

    private Button btn_one;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_one = findViewById(R.id.btn_one);
        btn_one.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setTitle("提示").setMessage("这是一个普通的对话框").setIcon(R.mipmap.icon_man).setCancelable(true);
                //设置正面按钮
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int i) {
                        Toast.makeText(MainActivity.this, "你点击了确定", Toast.LENGTH_SHORT).show();
                        dialog.dismiss();
                    }
                });

                //设置反面按钮
                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this, "你点击了取消", Toast.LENGTH_SHORT).show();
                        dialogInterface.dismiss();
                    }
                });
                //设置中立按钮
                builder.setNeutralButton("保密", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this, "你点击了保密", Toast.LENGTH_SHORT).show();
                        dialogInterface.dismiss();
                    }
                });

                AlertDialog dialog = builder.create();  //创建AlterDialog对象
                //对话框显示的监听事件
                dialog.setOnShowListener(new DialogInterface.OnShowListener() {
                    @Override
                    public void onShow(DialogInterface dialogInterface) {
                        Log.e("TAG", "对话框显示了");
                    }
                });

                //对话框消失的监听事件
                dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialogInterface) {
                        Log.e("TAG", "对话框消失了");
                    }
                });

                dialog.show();          //显示对话框
            }
        });
    }

Intent与IntentFilter

  • Action

     <action android:name="android.intent.action.MAIN" />
     intent.setAction(Intent.MAIN)
    
  • Category

    Category用于提供额外的附加类别信息,两者通常结合使用,一个Intent对象只能有一个Action,可以有多个

      <category android:name="android.intent.category.LAUNCHER" />
      intent.addCategorie(Intent.CATEGORY_LAUNCHER)
    
  • Data(数据), Type(MIME类型)

    Data同创用于向Action属性提供操作的数据,接收一个URI对象,URI的格式 scheme://host:port/path

    Type通常用于指定Data所制定的Uri对应的MIME类型,比如能够显示图片数据的组建不应该用来播放音频文件

    可以是自定义的MIME类型,只要符合abc/xyz格式的字符串就可以

      <data
          android:mimeType="Inetnt的type属性"
          android:scheme="Data的scheme协议头"
          android:host="Data的主机号"
          android:port="Data的端口号"
          android:path="Data的路径"
          android:pathPrefix="Data的path前缀"
          android:pathPattern="Data属性的path的字符串模板"
         / >
    
    
  • Extras(额外)

    通常用于多个Action之间的数据交换,Extras属性是一个Bundle对象,通过键值对进行数据的存储

    单个变量:intent.putintExtra(),getputExtra()
    Bundle:intent.putExtras(),getExtras()
    
  • Flags(标记)

    表示不同来源的标记,多数用于只是Android如何启动Activity以及启动后如何对待,标记都是定义在Intent类中,比如:FLAG_ACTIVITY)SINGLE_TOP:

    相当于加载模式总 singleTop模式,所有标记都是整数类型

           Intent intent = new Intent();
                    //点击返回主界面
    //                intent.setAction(Intent.ACTION_MAIN);
    //                intent.addCategory(Intent.CATEGORY_HOME);
    
                    //点击打开百度
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("http://www.baidu.com"));
                    startActivity(intent);
    
  • 隐式Intent

常用Intent合集

//===============================================================
//1.拨打电话
// 给移动客服10086拨打电话
Uri uri = Uri.parse("tel:10086");
Intent intent = new Intent(Intent.ACTION_DIAL, uri);
startActivity(intent);

//===============================================================

//2.发送短信
// 给10086发送内容为“Hello”的短信
Uri uri = Uri.parse("smsto:10086");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body", "Hello");
startActivity(intent);

//3.发送彩信(相当于发送带附件的短信)
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra("sms_body", "Hello");
Uri uri = Uri.parse("content://media/external/images/media/23");
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("image/png");
startActivity(intent);

//===============================================================

//4.打开浏览器:
// 打开百度主页
Uri uri = Uri.parse("http://www.baidu.com");
Intent intent  = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//===============================================================

//5.发送电子邮件:(阉割了Google服务的没戏!!!!)
// 给someone@domain.com发邮件
Uri uri = Uri.parse("mailto:someone@domain.com");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(intent);
// 给someone@domain.com发邮件发送内容为“Hello”的邮件
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, "someone@domain.com");
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Hello");
intent.setType("text/plain");
startActivity(intent);
// 给多人发邮件
Intent intent=new Intent(Intent.ACTION_SEND);
String[] tos = {"1@abc.com", "2@abc.com"}; // 收件人
String[] ccs = {"3@abc.com", "4@abc.com"}; // 抄送
String[] bccs = {"5@abc.com", "6@abc.com"}; // 密送
intent.putExtra(Intent.EXTRA_EMAIL, tos);
intent.putExtra(Intent.EXTRA_CC, ccs);
intent.putExtra(Intent.EXTRA_BCC, bccs);
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Hello");
intent.setType("message/rfc822");
startActivity(intent);

//===============================================================

//6.显示地图:
// 打开Google地图中国北京位置(北纬39.9,东经116.3)
Uri uri = Uri.parse("geo:39.9,116.3");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//===============================================================

//7.路径规划
// 路径规划:从北京某地(北纬39.9,东经116.3)到上海某地(北纬31.2,东经121.4)
Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=39.9 116.3&daddr=31.2 121.4");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//===============================================================

//8.多媒体播放:
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/foo.mp3");
intent.setDataAndType(uri, "audio/mp3");
startActivity(intent);

//获取SD卡下所有音频文件,然后播放第一首=-= 
Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//===============================================================

//9.打开摄像头拍照:
// 打开拍照程序
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
startActivityForResult(intent, 0);
// 取出照片数据
Bundle extras = intent.getExtras(); 
Bitmap bitmap = (Bitmap) extras.get("data");

//另一种:
//调用系统相机应用程序,并存储拍下来的照片
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
time = Calendar.getInstance().getTimeInMillis();
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment
.getExternalStorageDirectory().getAbsolutePath()+"/tucue", time + ".jpg")));
startActivityForResult(intent, ACTIVITY_GET_CAMERA_IMAGE);

//===============================================================

//10.获取并剪切图片
// 获取并剪切图片
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.putExtra("crop", "true"); // 开启剪切
intent.putExtra("aspectX", 1); // 剪切的宽高比为12
intent.putExtra("aspectY", 2);
intent.putExtra("outputX", 20); // 保存图片的宽和高
intent.putExtra("outputY", 40); 
intent.putExtra("output", Uri.fromFile(new File("/mnt/sdcard/temp"))); // 保存路径
intent.putExtra("outputFormat", "JPEG");// 返回格式
startActivityForResult(intent, 0);
// 剪切特定图片
Intent intent = new Intent("com.android.camera.action.CROP"); 
intent.setClassName("com.android.camera", "com.android.camera.CropImage"); 
intent.setData(Uri.fromFile(new File("/mnt/sdcard/temp"))); 
intent.putExtra("outputX", 1); // 剪切的宽高比为12
intent.putExtra("outputY", 2);
intent.putExtra("aspectX", 20); // 保存图片的宽和高
intent.putExtra("aspectY", 40);
intent.putExtra("scale", true);
intent.putExtra("noFaceDetection", true); 
intent.putExtra("output", Uri.parse("file:///mnt/sdcard/temp")); 
startActivityForResult(intent, 0);

//===============================================================

//11.打开Google Market 
// 打开Google Market直接进入该程序的详细页面
Uri uri = Uri.parse("market://details?id=" + "com.demo.app");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//===============================================================

//12.进入手机设置界面:
// 进入无线网络设置界面(其它可以举一反三)  
Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);  
startActivityForResult(intent, 0);

//===============================================================

//13.安装apk:
Uri installUri = Uri.fromParts("package", "xxx", null);   
returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);

//===============================================================

//14.卸载apk:
Uri uri = Uri.fromParts("package", strPackageName, null);      
Intent it = new Intent(Intent.ACTION_DELETE, uri);      
startActivity(it); 

//===============================================================

//15.发送附件:
Intent it = new Intent(Intent.ACTION_SEND);      
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");      
it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/eoe.mp3");      
sendIntent.setType("audio/mp3");      
startActivity(Intent.createChooser(it, "Choose Email Client"));

//===============================================================

//16.进入联系人页面:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(People.CONTENT_URI);
startActivity(intent);

//===============================================================


//17.查看指定联系人:
Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, info.id);//info.id联系人ID
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(personUri);
startActivity(intent);

//===============================================================

//18.调用系统编辑添加联系人(高版本SDK有效):
Intent it = newIntent(Intent.ACTION_INSERT_OR_EDIT);    
it.setType("vnd.android.cursor.item/contact");    
//it.setType(Contacts.CONTENT_ITEM_TYPE);    
it.putExtra("name","myName");    
it.putExtra(android.provider.Contacts.Intents.Insert.COMPANY, "organization");    
it.putExtra(android.provider.Contacts.Intents.Insert.EMAIL,"email");    
it.putExtra(android.provider.Contacts.Intents.Insert.PHONE,"homePhone");    
it.putExtra(android.provider.Contacts.Intents.Insert.SECONDARY_PHONE,"mobilePhone");    
it.putExtra( android.provider.Contacts.Intents.Insert.TERTIARY_PHONE,"workPhone");    
it.putExtra(android.provider.Contacts.Intents.Insert.JOB_TITLE,"title");    
startActivity(it);

//===============================================================

//19.调用系统编辑添加联系人(全有效):
Intent intent = newIntent(Intent.ACTION_INSERT_OR_EDIT);    
intent.setType(People.CONTENT_ITEM_TYPE);    
intent.putExtra(Contacts.Intents.Insert.NAME, "My Name");    
intent.putExtra(Contacts.Intents.Insert.PHONE, "+1234567890");    
intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE,Contacts.PhonesColumns.TYPE_MOBILE);    
intent.putExtra(Contacts.Intents.Insert.EMAIL, "com@com.com");    
intent.putExtra(Contacts.Intents.Insert.EMAIL_TYPE, Contacts.ContactMethodsColumns.TYPE_WORK);    
startActivity(intent);

//===============================================================

//20.打开另一程序 
Intent i = new Intent();     
ComponentName cn = new ComponentName("com.example.jay.test",     
"com.example.jay.test.MainActivity");     
i.setComponent(cn);     
i.setAction("android.intent.action.MAIN");     
startActivityForResult(i, RESULT_OK);

//===============================================================

//21.打开录音机
Intent mi = new Intent(Media.RECORD_SOUND_ACTION);     
startActivity(mi);

//===============================================================

//22.从google搜索内容 
Intent intent = new Intent();     
intent.setAction(Intent.ACTION_WEB_SEARCH);     
intent.putExtra(SearchManager.QUERY,"searchString")     
startActivity(intent);

//===============================================================

四大组件之Activity

  • 启动一个Activity的几种方式

    • 显示启动: 通过包名来启动,写法如下

      //1.最常见的
      startActivity(new Intent(当前Act.this,要启动的Act.class));
      
      //通过Intent的ComponentName:
      ComponentName cn = new ComponentName("当前Act的全限定类名","启动Act的全限定类名") ;
      Intent intent = new Intent() ;
      intent.setComponent(cn) ;
      startActivity(intent) ;
      
      //初始化Intent时指定包名:
      Intent intent = new Intent("android.intent.action.MAIN");
      intent.setClassName("当前Act的全限定类名","启动Act的全限定类名");
      startActivity(intent);
      
    • 隐式启动: 通过Intent-filter的Action,Category或data来实现 这个是通过Intent的intent-filter来实现的

       <activity android:name=".MainActivity3"
               android:label="第三个Activity">
               <intent-filter>
                   <action android:name="third_action"/>
                   <category android:name="third_category"/>
                   <category android:name="android.intent.category.DEFAULT" />
               </intent-filter>
       </activity>
      
      //启动第三个activity
                  Intent it = new Intent();
                  it.setAction("third_action");
                  it.addCategory("third_category");
                  startActivity(it);
      
    • 直接通过包名启动apk:

      Intent intent = getPackageManager().getLaunchIntentForPackage
      ("apk第一个启动的Activity的全限定类名") ;
      if(intent != null) startActivity(intent) ;
      
  • 横竖屏切换与状态保存

    <activity
        android:name=".MainActivity3"
        android:label="第三个Activity"
        android:screenOrientation="横竖屏">
        <intent-filter>
            <action android:name="third_action" />
            <category android:name="third_category" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    
    • unspecified:默认值 由系统来判断显示方向.判定的策略是和设备相关的,所以不同的设备会有不同的显示方向。
    • landscape:横屏显示(宽比高要长)
    • portrait:竖屏显示(高比宽要长)
    • user:用户当前首选的方向
    • behind:和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)
    • sensor:有物理的感应器来决定。如果用户旋转设备这屏幕会横竖屏切换。
    • nosensor:忽略物理感应器,这样就不会随着用户旋转设备而更改了("unspecified"设置除外)。
  • Activity间的数据传递

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vn79vvF2-1616552745252)(imgs/activity_data_pass.jpg)]

四大组件之Service

StartService启动Service的调用顺序

TestService1.java

public class TestService1 extends Service {
    private final String TAG = "TestService1";

    public TestService1() {
    }

    //必须要实现的方法
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
//        throw new UnsupportedOperationException("Not yet implemented");
        Log.i(TAG, "onBind方法被调用");
        return null;
    }

    //Service被创建时调用
    @Override
    public void onCreate() {
        Log.i(TAG, "onCreate方法被调用!");
        super.onCreate();
    }

    //Service被启动时调用
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand方法被调用!");
        return super.onStartCommand(intent, flags, startId);
    }

    //Service被关闭之前回调
    @Override
    public void onDestroy() {
        Log.i(TAG, "onDestory方法被调用!");
        super.onDestroy();
    }
}

AndroidManifest.xml完成Service注册

<service
    android:name=".TestService1"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.myapplication.TEST_SERVICE1"/>
    </intent-filter>
</service>

MainActivity 启动 Service的编写

//创建启动Service的Intent,以及Intent属性
final Intent intent = new Intent();
intent.setAction("com.example.myapplication.TEST_SERVICE1");
intent.setPackage("com.example.myapplication");
//为两个按钮设置点击事件,分别是启动与停止service
btn_start.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        startService(intent);
    }
});

btn_stop.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        stopService(intent);
    }
});

结果分析

onBind()方法并没有被调用,多次点击Service,只会重复的调用onStartCommand方法!无论我们启动多少次Service,一个StopService就会停止Service!

验证BindService启动Service的调用顺序

  • ServiceConnection对象:监听访问者与Service间的连接情况,如果成功连接,回调 onServiceConnected(),如果异常终止或者其他原因终止导致Service与访问者断开 连接则回调onServiceDisconnected方法,调用unBindService()不会调用该方法!
  • onServiceConnected**方法中有一个IBinder对象,该对象即可实现与被绑定Service 之间的通信!**我们再开发Service类时,默认需要实现IBinder onBind()方法,该方法返回的 IBinder对象会传到ServiceConnection对象中的onServiceConnected的参数,我们就可以 在这里通过这个IBinder与Service进行通信!
Service问题:
java.lang.NullPointerException: Attempt to invoke virtual method 'int com.example.myapplication.TestService2$MyBinder.getCount()' on a null object reference

在service中定义的count变量,无法获取,定义的线程不执行

public class TestService2 extends Service {
    private final String TAG = "TestService2";
    private int count=1;
    private boolean quit;

    public TestService2() {
    }

    //定义onbinder方法所返回的对象
    private MyBinder binder = new MyBinder();

    public class MyBinder extends Binder {
        public int getCount() {
            return count;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind方法被调用!");
        Log.i(TAG, "count值为!"+count);
        return binder;
    }

    //Service被创建时回调
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate方法被调用!");
        //创建一个线程动态的修改count的值
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count++;
                }
            }
        }.start();
    }
    //Service断开连接时回调
    @Override
    public boolean onUnbind(Intent intent) {
        Log.i(TAG, "onUnbind方法被调用!");
        return true;
    }
    //Service被关闭前回调
    @Override
    public void onDestroy() {
        super.onDestroy();
        this.quit = true;
        Log.i(TAG, "onDestroyed方法被调用!");
    }
    @Override
    public void onRebind(Intent intent) {
        Log.i(TAG, "onRebind方法被调用!");
        super.onRebind(intent);
    }
  • bindService中Intent所担任的角色?绑定service
  • Service中ServiceConnected对象来监听访问者与service间的连接情况,如果成功连接或者失败连接都会调用相应的方法.
  • ServiceConnected中Ibinder对象实现与被绑定的Service之间的通信,开发service类时,默认需要实现IBinder onBind()方法,该方法返回的IBinder对象会传到ServiceCOnnection对象中的onServiceConnected的参数,我们就可以在这里通过这个IBinder与Service进行通信
    在这里插入图片描述
    MainActivity.java
public class MainActivity extends AppCompatActivity {

    //bindService
    private Button btn_bind;
    private Button btn_cancel;
    private Button btn_status;

    //保持所启动的Service的IBinder对象,同时定义一个ServiceConnection对象
    TestService2.MyBinder binder;
    private ServiceConnection conn = new ServiceConnection() {
        //Activity与Service连接成功时回调该方法
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            //通过这个IBinder与Service进行通信
            System.out.println("----------------Service Connected---------------");
            binder = (TestService2.MyBinder) service;
        }

        //Activity与Service断开连接时回调该方法
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            System.out.println("------Service DisConnected-------");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        //bindService
        btn_bind = findViewById(R.id.btn_bind);
        btn_cancel = findViewById(R.id.btn_cancel);
        btn_status = findViewById(R.id.btn_status);
        final Intent it1 = new Intent();
        it1.setAction("com.example.myapplication.TEST_SERVICE2");
        it1.setPackage("com.example.myapplication");


        btn_bind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //锁定Service
                bindService(it1, conn, Service.BIND_AUTO_CREATE);
            }
        });

        btn_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //解除锁定
                unbindService(conn);
            }
        });
        //获取Service状态
        btn_status.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(getApplicationContext(), "Service的count的值为:"
                        + binder.getCount(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

IntentService的使用

public class TestService3 extends IntentService {

    private final String TAG = "hehe";


    public TestService3() {
        super("TestService3");
    }


    //必须重写的核心方法
    @Override
    protected void onHandleIntent(Intent intent) {
        //Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务
        String action = intent.getExtras().getString("param");
        if (action.equals("s1")) Log.i(TAG, "启动service1");
        else if (action.equals("s2")) Log.i(TAG, "启动service2");
        else if (action.equals("s3")) Log.i(TAG, "启动service3");

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //重写其他方法,用于查看方法的调用顺序
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG,"onBind");
        return super.onBind(intent);
    }

    @Override
    public void onCreate() {
        Log.i(TAG,"onCreate");
        super.onCreate();
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        Log.i(TAG,"onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void setIntentRedelivery(boolean enabled) {
        super.setIntentRedelivery(enabled);
        Log.i(TAG,"setIntentRedelivery");
    }

    @Override
    public void onDestroy() {
        Log.i(TAG,"onDestroy");
        super.onDestroy();
    }
}

Acitvity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Intent it1 = new Intent("com.example.myapplication.intentservice");
    it1.setPackage("com.example.myapplication");
    Bundle b1 = new Bundle();
    b1.putString("param", "s1");
    it1.putExtras(b1);

    Intent it2 = new Intent("com.example.myapplication.intentservice");
    it2.setPackage("com.example.myapplication");
    Bundle b2 = new Bundle();
    b2.putString("param", "s2");
    it2.putExtras(b2);

    Intent it3 = new Intent("com.example.myapplication.intentservice");
    it3.setPackage("com.example.myapplication");
    Bundle b3 = new Bundle();
    b3.putString("param", "s3");
    it3.putExtras(b3);

    //接着启动多次IntentService,每次启动都会创建一个工作线程
    //但始终只要一个IntentService实例
    startService(it1);
    startService(it2);
    startService(it3);
}

四大组件之BroadcastReceiver

1>注册广播的方式

  • 动态注册

    就是Java代码中指定IntentFilter,然后添加不同的Action即可,想监听什么广播就写什么Action,另外动态注册的广播,一定要调用unregisterReceiver让广播取消注册

  • 静态注册

    动态注册需要程序启动后才能接受广播,静态广播就弥补了这个短板,在AndroidManifest中订制就可以让程序在未启动的情况下接收广播了

2>动态注册实例(监听网络状态变化)

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"网络状态发生改变~", Toast.LENGTH_SHORT).show();
    }
}

Mainfest

<receiver
    android:name=".broadres.MyReceiver"
    android:enabled="true"
    android:exported="true">
</receiver>

Activity

public class MainActivity extends AppCompatActivity {
    MyReceiver myReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //核心代码
        myReceiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        registerReceiver(myReceiver, intentFilter);
    }

    //取消广播
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(myReceiver);
    }
}

3>静态注册实例(接收开机广播)

4>发送广播(●’◡’●)

布局神器 Fragment

fragment静态加载

fragment动态加载

ListView优化

ViewHolder

启动该一个Activity的几种方式

显示启动:通过包名来启动,写法如下

  1. 最常见的:

    startActivity(new Intennt(当前Act.this,要启动的Act.class));
    
  2. 通过Intent的ComponetName:

    ComponentName cn=new ComponentName("当前Act的全限定类名","启动Act的全限定类名");
    Intent intent =new Intent();
    intent.setComponent(cn);
    startActivity(intent);
    
  3. 初始化Intent时指定包名:

    Intent intent = new Intent("android.intent.action.MAIN");
    intent.setClassName("当前Act的全限定类名","启动Act的全限定类名");
    startActivity(intent);
    

    activity给Fragment传递数据通信

一 通过自定义接口来实现

该方法没有使用Bundle 来传递数据,而是通过接口来进行监听作用

定义一个接口,作为监听器来使用=====>>测试接口作为某个实体类的监听器

public interface ToFragmentListener {
    void onTypeClick(String message);
}

该接口中只要一个方法就是接受信息并作出操作

Fragment实现该方法

public class BasicFragment extends Fragment implements ToFragmentListener{
    ...
private View initView() {
        FrameLayout rootView = (FrameLayout) LayoutInflater.from(this.getContext()).inflate(R.layout.fragment_basic, null);
        //获取Fragment中的组件
        textView_basic_main = rootView.findViewById(R.id.textView_basic_main);
        return rootView;
    }
        @Override
    public void onTypeClick(String message) {
        //为组件赋值
        textView_basic_main.setText(message);
    }
}

在Activtiy中,创建该Fragment实例对象,并赋值给接口==>>>多态??

通过接口来调用方法,在方法中传递需要传递的参数android:background="#E0E0E0"


public class MainActivity extends FragmentActivity {
/*
    fragment
 */
private ToFragmentListener mFragmentListener;
private BasicFragment basicFragment;
      @Override
    protected void onCreate(Bundle savedInstanceState) {
        //为fragment对象赋值
        basicFragment = new BasicFragment();
         //这步是关键,因为Fragment实现了该接口,所以可以直接把Fragment实例赋值给接口引用
        mFragmentListener = basicFragment;
    }
     /**
     * 测试按钮
     * @param view
     */
    public void fun_test(View view) {
        if(null != mFragmentListener){
            mFragmentListener.onTypeClick("来自Activity的实时数据");
        }
    }
}

二 通过bundle来传递数据

步骤1: 创建布局文件

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:text="我是Activity" />

    <FrameLayout
        android:layout_below="@+id/fragment_container"
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="500dp"/>
</LinearLayout>

步骤2: 定义activity

public class MainActivity extends AppCompatActivity {

    TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = findViewById(R.id.text);

        //步骤1: 创建fragment
        myfragment myfragment = new myfragment();
        Bundle bundle = new Bundle();
        bundle.putString("message", "wocaonima");
        myfragment.setArguments(bundle);

        //步骤2: 获取Fragment对象
        getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, myfragment).commit();
    }
}

步骤3: 定义fragment布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/purple_200"
    >

    <TextView
        android:id="@+id/fragment"
        android:text="我是fragment"
        android:layout_gravity="center"
        android:textSize="30dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <TextView
        android:id="@+id/text"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:text="等待Activity发送消息" />

    <Button
        android:id="@+id/button"
        android:layout_gravity="center"
        android:text="点击接收Activity消息"
        android:layout_centerInParent="true"
        android:textSize="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

步骤4: 创建fragment

public class myfragment extends Fragment {
    Button button;
    TextView text;
    Bundle bundle;
    String message;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.fragment, container, false);
        //设置布局文件
        button = contentView.findViewById(R.id.button);
        text= contentView.findViewById(R.id.text);
        //步骤1 通过getArgments()获取从Activity传过来的全部值
        bundle = this.getArguments();

        //步骤2 获取某一值
        message = bundle.getString("message");

        //步骤3 设置按钮,将设置的值显示出来
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                text.setText(message);
            }
        });

        return contentView;
    }
}

fragment给activity传递数据

采用接口回调方式

接口回调:

把实现了某一个接口的类所创建的引用赋给该接口声明的变量,通过该接口变量 调用该实现类对象的实 现的接口方法

// 接口声明的变量
Com com;

// 实现了Com接口的类(Com1)所创建的对象的引用 赋给 该接口声明的变量
Com com = new Com1;

// 通过该接口变量(com) 调用 该实现类对象(Com1)的实现的接口方法(carson())
com.carson()
  • 步骤1:在Activity的布局文件定义1占位符(FrameLayout

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="scut.carson_ho.fragment_2_activity.MainActivity">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:text="等待Fragment发送消息" />

    <Button
        android:id="@+id/button"
        android:layout_below="@+id/text"
        android:text="点击接收Fragment消息"
        android:layout_centerInParent="true"
        android:textSize="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <FrameLayout
        android:layout_below="@+id/button"
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="500dp"/>

</RelativeLayout>
  • 步骤2:设置Fragment的布局文件

fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <TextView
        android:id="@+id/fragment"
        android:text="我是fragment"
        android:gravity="center"
        android:textSize="30dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent"/>

</LinearLayout>
  • 步骤3:设置回调接口
    该接口用于用于ActivityFragment通信

ICallBack.java

public interface ICallBack {
    void get_message_from_Fragment(String string);

}
  • 步骤4:设置Fragment的类文件

mFragment.java

public class mFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.fragment, container, false);
        // 设置布局文件
        return contentView;
    }

    // 设置 接口回调 方法
    public void sendMessage(ICallBack callBack){

        callBack.get_message_from_Fragment("消息:我来自Fragment");

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪随安

朝看天色暮看云行也思君坐也思君

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值