android音乐播放器(Service+ContentProvider+Broadcast+Activity四大组件完成)

时间:2022-08-29 20:01:21

1、获取音乐

  1-1:获取手机中的音乐(用ContentProvider内容提供者来完成):

 package com.firefly.util;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import android.util.Log; public class MediaUtil {
/**
* 用于从数据库中查询歌曲的信息,保存在List当中
*
* @return
*/
public static List<Mp3Info> getMp3Infos(Context context) {
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
List<Mp3Info> mp3Infos = new ArrayList<Mp3Info>(); for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
Mp3Info mp3Info = new Mp3Info();
long id = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media._ID)); // 音乐id
String title = cursor.getString((cursor
.getColumnIndex(MediaStore.Audio.Media.TITLE))); // 音乐标题
String artist = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST)); // 艺术家
long duration = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.DURATION)); // 时长
long size = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.SIZE)); // 文件大小
String url = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA)); // 文件路径
int isMusic = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC)); // 是否为音乐
if (isMusic != 0) { // 只把音乐添加到集合当中 mp3Info.setId(id);
mp3Info.setTitle(title);
mp3Info.setArtist(artist);
mp3Info.setDuration(duration);
mp3Info.setSize(size);
mp3Info.setUrl(url); mp3Infos.add(mp3Info);
}
}
return mp3Infos;
} /**
* 格式化时间,将毫秒转换为分:秒格式
*
* @param time
* @return
*/
public static String formatTime(long time) {
String min = time / (1000 * 60) + "";
String sec = time % (1000 * 60) + "";
if (min.length() < 2) {
min = "0" + time / (1000 * 60) + "";
} else {
min = time / (1000 * 60) + "";
}
if (sec.length() == 4) {
sec = "0" + (time % (1000 * 60)) + "";
} else if (sec.length() == 3) {
sec = "00" + (time % (1000 * 60)) + "";
} else if (sec.length() == 2) {
sec = "000" + (time % (1000 * 60)) + "";
} else if (sec.length() == 1) {
sec = "0000" + (time % (1000 * 60)) + "";
}
return min + ":" + sec.trim().substring(0, 2);
}
}

MediaUtil

  1-2:写实体类来存放获取的音乐数据

 package com.firefly.util;

 public class Mp3Info {
public long id; // 音乐id
public String title;// 音乐标题
public String artist;// 艺术家
public long duration; // 时长
public long size;// 文件大小
public String url;// 文件路径
public int isMusic;// 是否为音乐 public long getId() {
return id;
} public void setId(long id) {
this.id = id;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getArtist() {
return artist;
} public void setArtist(String artist) {
this.artist = artist;
} public long getDuration() {
return duration;
} public void setDuration(long duration) {
this.duration = duration;
} public long getSize() {
return size;
} public void setSize(long size) {
this.size = size;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public int getIsMusic() {
return isMusic;
} public void setIsMusic(int isMusic) {
this.isMusic = isMusic;
} }

Mp3Info

  1-3:写适配器来将音乐数据初始化

 package com.firefly.util;

 import java.util.List;

 import com.firefly.beautifulmusic.R;

 import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView; public class MusicAdapter extends BaseAdapter {
List<Mp3Info> datas;
LayoutInflater inflater;
int index = -1; // 把当前位置传过来
public void setIndex(int index) {
this.index = index;
} public MusicAdapter(Context context, List<Mp3Info> datas) {
this.inflater = LayoutInflater.from(context);
this.datas = datas;
} @Override
public int getCount() {
// TODO Auto-generated method stub
return datas.size();
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return datas.get(position);
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_music_list, null);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.item_title);
holder.duration = (TextView) convertView
.findViewById(R.id.item_duration);
holder.artist = (TextView) convertView
.findViewById(R.id.item_artist);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Mp3Info music = datas.get(position);
holder.title.setTag(music);
holder.title.setText(music.getTitle());
holder.artist.setText(music.getArtist());
// 获取时间并改变它的格式
Long time = music.getDuration();
long min = (time / 1000) / 60;
long second = (time / 1000) % 60;
holder.duration.setText(min + ":" + second);
if (position == index) {
// 如果正在播放当前项,就改其颜色
holder.title.setTextColor(Color.parseColor("#E34C36"));
holder.duration.setTextColor(Color.parseColor("#E34C36"));
holder.artist.setTextColor(Color.parseColor("#E34C36"));
} else {
// 否则的话则回到原来的状态
holder.title.setTextColor(Color.BLACK);
holder.duration.setTextColor(Color.BLACK);
holder.artist.setTextColor(Color.BLACK);
}
return convertView;
} static class ViewHolder {
public TextView title;
public TextView duration;
public TextView artist;
} }

MusicAdapter

  1-4:(可不参考)用来适配的素材xml

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" > <TextView
android:id="@+id/item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="歌名" /> <TextView
android:id="@+id/item_artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="歌手" />
</LinearLayout> <TextView
android:id="@+id/item_duration"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="4"
android:text="时长" /> </LinearLayout>

item_music_list

2、在主页面中进行初始化数据

  2-1:xml页面布局

 <LinearLayout 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:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" > <ListView
android:id="@+id/lv_musicList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
</ListView> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" > <Button
android:id="@+id/btnUp"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/up"
android:onClick="playMusic" /> <Button
android:id="@+id/btnPlay"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="@drawable/pause"
android:onClick="playMusic" /> <Button
android:id="@+id/btnDown"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/down"
android:onClick="playMusic" />
</LinearLayout> <SeekBar
android:id="@+id/sb"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> </LinearLayout>

activity_main

  2-2:在其相对应的Activiity文件中初始化数据

 package com.firefly.beautifulmusic;

 import java.io.File;
import java.util.List; import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast; import com.firefly.service.MusicService;
import com.firefly.service.MusicService.MyBinder;
import com.firefly.util.MediaUtil;
import com.firefly.util.Mp3Info;
import com.firefly.util.MusicAdapter; public class MainActivity extends Activity {
ServiceConnection conn;
MusicService ms;
String music_name;
File f;
Boolean isPlay = false;
ListView lv;
MusicAdapter adapter;
List<Mp3Info> datas;
Button btn;
int current;
SeekBar sb; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化数据
init();
} private void init() {
btn = (Button) findViewById(R.id.btnPlay);
lv = (ListView) findViewById(R.id.lv_musicList);
//获取手机中 的音乐数据
datas = MediaUtil.getMp3Infos(MainActivity.this);
sb = (SeekBar) findViewById(R.id.sb);
adapter = new MusicAdapter(MainActivity.this, datas);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//点击哪一项就播放哪一项(前提条件是它是音乐文件)
current = position;
f = new File(datas.get(current).getUrl());
if (f.exists() && f.length() > 0) {
play();
} else {
Toast.makeText(getApplicationContext(), "该文件不是音乐", 0)
.show();
}
}
});
// 注册广播
broadcast();
// 服务
service();
} private void broadcast() {
// TODO Auto-generated method stub
MusicBroadcast mb = new MusicBroadcast();
IntentFilter ifilter = new IntentFilter();
ifilter.addAction("com.firefly.music");
ifilter.addAction("android.intent.action.PHONE_STATE");
registerReceiver(mb, ifilter);
Log.e("TAG", "动态注册成功");
} private void service() {
// TODO Auto-generated method stub
conn = new ServiceConnection() { @Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub } @Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
MyBinder binder = (MyBinder) service;
ms = binder.getService();
ms.setSeekBar(sb);
}
}; // 绑定服务
Intent i = new Intent(this, MusicService.class);
bindService(i, conn, BIND_AUTO_CREATE);
} public void playMusic(View v) {
switch (v.getId()) {
case R.id.btnPlay:
if (isPlay == false) {
play();
} else {
pause();
}
break;
// 上一首
case R.id.btnUp:
if (isPlay) {
if ((current - 1) >= 0) {
--current;
f = new File(datas.get(current).getUrl());
play();
} else {
Toast.makeText(getApplicationContext(), "已经是第一首了", 0).show();
}
}
break;
// 下一首
case R.id.btnDown:
if ((current + 1) < datas.size()) {
++current;
f = new File(datas.get(current).getUrl());
play();
} else {
Toast.makeText(getApplicationContext(), "已经是最后一首了", 0).show();
}
break; default:
break;
}
} //播放
public void play() {
//调用服务中的播放方法
ms.PlayMusic(f.getAbsolutePath());
btn.setBackgroundResource(R.drawable.play);
isPlay = true;
// 如果在播放中,就改变它的样式
adapter.setIndex(current);
adapter.notifyDataSetChanged();
} //暂停
public void pause() {
//调用服务中的暂停方法
ms.PauseMusic();
btn.setBackgroundResource(R.drawable.pause);
isPlay = false;
} // 新建广播
public class MusicBroadcast extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
// 接收广播
if (intent.getAction() == "com.firefly.music") {
if (intent.getStringExtra("end").equals("播放完毕")) {
if ((current + 1) < datas.size()) {
//如果播放完毕了,就播放下一首
f = new File(datas.get(++current).getUrl());
play();
} else {
Toast.makeText(getApplicationContext(), "已经是最后一首了", 0)
.show();
}
}
} else if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
//电话监听事件,如果要拨打电话就暂停音乐
String rs = getResultData();
Toast.makeText(context, "你在拨打" + rs + "的电话了,现在我已经暂停音乐了。", 0).show();
pause();
} else {
//来电也要暂停音乐
TelephonyManager telMan = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
// 判断电话的状态
switch (telMan.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING:
Log.e("TAG", "响铃");
Toast.makeText(getApplicationContext(), "来电话了", 0).show();
pause();
break; case TelephonyManager.CALL_STATE_IDLE:
Log.e("TAG", "挂断");
Toast.makeText(getApplicationContext(), "您已经挂断,音乐将继续播放", 0).show();
play();
break; case TelephonyManager.CALL_STATE_OFFHOOK:
Log.e("TAG", "接听");
Toast.makeText(getApplicationContext(), "您正在接收电话,音乐已经暂停", 0).show();
pause();
break; default:
break;
}
}
} }
}

  2-3:写一个接口类,统一管理服务(也可不写)

 package com.firefly.service;

 public interface IMusic {
// 新建一个接口,能用服务来实现它,在这里可以统一管理
public void PlayMusic(String music_name); public void PauseMusic(); public void PreviousMusic(); public void NextMusic();
}

IMusic

  2-4:服务类

 package com.firefly.service;

 import android.app.Service;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast; public class MusicService extends Service implements IMusic {
MediaPlayer music;
String music_name;
SeekBar sb;
Handler handler;
boolean flag = false;// 控制线程的播放 @Override
public void PlayMusic(String music_name) {
this.music_name = this.music_name;
if (music != null && music.isPlaying()) {
// 如果在播放的状态下切换到下一首,先把原来的停止、释放、置空,再新建
music.stop();
music.release();
music = null;
try {
music = new MediaPlayer();
music.setAudioStreamType(AudioManager.STREAM_MUSIC);
music.setDataSource(music_name);
music.prepare();
music.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else { if (music != null) {// 这个状态可能是暂停可能是停止
// 如果只是把它暂停,重新开始就可以了
music.start();
} else {
// 第一次播放这首音乐
try {
music = new MediaPlayer();
music.setAudioStreamType(AudioManager.STREAM_MUSIC);
music.setDataSource(music_name);
music.prepareAsync();
// 准备监听事件
music.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
music.start();
// 设置SeekBar
int max = music.getDuration();
int cur = music.getCurrentPosition();
Log.e("TAG", max + "==" + cur);
sb.setMax(max);
sb.setProgress(cur);
sb.setEnabled(true);
}
});
// 音乐播放完毕的监听器
music.setOnCompletionListener(new OnCompletionListener() { @Override
public void onCompletion(MediaPlayer mp) {
music.stop();
music.release();
music = null;
// 发送一个广播,已经播放完毕了
Intent i = new Intent();
i.setAction("com.firefly.music");
i.putExtra("end", "播放完毕");
sendBroadcast(i); }
});
} catch (Exception e) {
e.printStackTrace();
}
}
flag = true;
}
// 这个线程用来控制进度条的更新
Thread th = new Thread(new Runnable() { @Override
public void run() {
while (flag) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg = new Message();
msg.what = 0;
handler.sendMessage(msg);
}
}
});
th.start(); } @Override
public void PauseMusic() {
// TODO Auto-generated method stub
if (music != null && music.isPlaying()) {
music.pause();
flag = false;
}
} @Override
public void PreviousMusic() {
// TODO Auto-generated method stub } @Override
public void NextMusic() {
// TODO Auto-generated method stub } public void setSeekBar(final SeekBar sb) {
this.sb = sb;
sb.setEnabled(false);// 没开始播放的时候进度条是不能拖动的
sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
if (music != null) {
music.seekTo(seekBar.getProgress());
}
} @Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub } @Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub }
}); handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
if (music != null) {
// 播放和SeekBar同步
sb.setProgress(music.getCurrentPosition());
}
break; default:
break;
}
} }; } @Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new MyBinder();
} public class MyBinder extends Binder {
public MusicService getService() {
return MusicService.this;
}
} }

MusicService

3、清单文件

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.firefly.beautifulmusic"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<!-- 读写SD卡的权限、读取电话状态的权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <service android:name="com.firefly.service.MusicService" >
</service>
</application> </manifest>

Manifest

4、效果图

android音乐播放器(Service+ContentProvider+Broadcast+Activity四大组件完成)

android音乐播放器(Service+ContentProvider+Broadcast+Activity四大组件完成)的更多相关文章

  1. Android音乐播放器源码&lpar;歌词&period;均衡器&period;收藏&period;qq5&period;0菜单&period;通知&rpar;

    一款Android音乐播放器源码,基本功能都实现了 qq5.0菜单(歌词.均衡器.收藏.qq5.0菜单.通知) 只有向右滑动出现,菜单键和指定按钮都还没有添加. 源码下载:http://code.66 ...

  2. 一款非常简单的android音乐播放器源码分享给大家

    一款非常简单的android音乐播放器源码分享给大家,该应用虽然很小,大家常用的播放器功能基本实现了,可能有点还不够完善,大家也可以自己完善一下,源码在源码天堂那里已经有了,大家可以到那里下载学习吧. ...

  3. android音乐播放器开发教程

    android音乐播放器开发教程 Android扫描sd卡和系统文件 Android 关于录音文件的编解码 实现米聊 微信一类的录音上传的功能 android操作sdcard中的多媒体文件——音乐列表 ...

  4. android 音乐播放器

    本章以音乐播放器为载体,介绍android开发中,通知模式Notification应用.主要涉及知识点Notification,seekbar,service. 1.功能需求 完善音乐播放器 有播放列 ...

  5. Android音乐播放器的开发实例

    本文将引导大家做一个音乐播放器,在做这个Android开发实例的过程中,能够帮助大家进一步熟悉和掌握学过的ListView和其他一些组件.为了有更好的学习效果,其中很多功能我们手动实现,例如音乐播放的 ...

  6. android音乐播放器开发 SweetMusicPlayer 播放本地音乐

    上一篇写了载入歌曲列表,http://blog.csdn.net/huweigoodboy/article/details/39856411,如今来总结下播放本地音乐. 一,MediaPlayer 首 ...

  7. Android音乐播放器开发

    今日看书,看到这个播放器,我就写了个例子,感觉还行,这个播放器能播放后缀是.MP3的音乐,这个例子在main.xml设置listView的时候,注意:android:id="@+id/and ...

  8. 【竞品分析】Android音乐播放器的竞品分析

    迄今为止最长的一篇博客,各位看官笑纳~~ 本次分析基于Android平台,选取了几款我体验过的播放器进行比较分析.主要分为两类,一类是大而全的,功能全面,可满足用户管理歌曲.导入导出歌单等多方面需求, ...

  9. Android音乐播放器的设计与实现

    目录 应用开发技术及开发平台介绍 应用需求分析 应用功能设计及其描述 应用UI展示 一.应用开发技术及平台介绍 ①开发技术: 本系统是采用面向对象的软件开发方法,基于Android studio开发平 ...

随机推荐

  1. &lpar;转&rpar;CDN——到底用还是不用?

    用CDN的七个理由 浏览器从服务器上下载css.js和图片等文件时都要和服务器连接,而大部分浏览器对同一个域名用于下载文件的并发连接数限制在4个,这意味着如果要下载第五个文件就必须等前四个文件中有一个 ...

  2. hibernate添加数据&comma;默认字段为null的问题解决

    数据库中的一个字段默认为0,但是在用hibernate的添加之后,默认字段竟然不是0,为NULL. 查了一下.发现想要让默认字段生效.需要在*.hbm.xml添加一些参数,如下.(红色部分) dyna ...

  3. TestNG操作详解

    运行测试步骤方法有如下两种: 1. 直接在Eclipse运行testNG的测试用例, 在代码编辑区域鼠标右键, 选择Run as ->testNG Test 2. 在工程的根目录下, 建立tes ...

  4. &lbrack;Swift&rsqb;LeetCode896&period; 单调数列 &vert; Monotonic Array

    An array is monotonic if it is either monotone increasing or monotone decreasing. An array A is mono ...

  5. 在java中使用Mysql数据库,如何在MyBatis的xml里面处理时间为Int类型的数据

    主要是将显示在页面上的数据变成日期格式,而不是相应的毫秒数,具体的做法如下: 1.首先需要在相关的xml文件里面修改时间为下面语句,其中reg_time为要修改的日期列名 FROM_UNIXTIME( ...

  6. Docker 从入门到实践(一)Docker 简介

    读前须知:本教程大部分都是[Docker 从入门到实践 ]一书的知识,有兴趣可以直接观看书籍.同时,借鉴书籍的知识,如有侵权,请告知我,我会删除处理.谢谢. 一.什么是 Docker? Docker ...

  7. JAVA中有一个特殊的类: Object。它是JAVA体系中所有类的父类(直接父类或者间接父类)。

    接口往往被我们定义成一类XX的东西. 接口实际上是定义一个规范.标准.   ①  通过接口可以实现不同层次.不同体系对象的共同属性: 通过接口实现write once as anywhere. 以JA ...

  8. 这可能是史上最全的css布局教程

    标题严格遵守了新广告法,你再不爽,我也没犯法呀!话不多说,直入正题. 所谓布局,其实包含两个含义:尺寸与定位.也就是说,所有与尺寸和定位相关的属性,都可以用来布局. 大体上,布局中会用到的有:尺寸相关 ...

  9. centos7在vmware上安装后不能连接网络的问题。注意虚拟机向导时选择的操作系统&period;&period;&period;&period;&period;&period;&period;&period;&period;&period;&period;

    在虚拟机上安装时发现网络不可用 在网上查找解决方案一整理天,各种命令代码偿试   无效. 在贴上发现说 Centos7镜像是64位 ,虚拟机操作系统一定要选择centos64位也是必须的. 最后选择重 ...

  10. Python 爬取bangumi网页信息

    1.数据库连接池 #######db.py########## import time import pymysql import threading from DBUtils.PooledDB im ...