Android项目实战系列—基于博学谷(七)课程模块(中)

news/2024/7/6 1:14:22

image

由于这个模块内容较多,分为上、中、下 三篇博客分别来讲述,请耐心阅读。


课程模块分为四个部分

  • 课程列表
  • 课程详情
  • 视频播放
  • 播放记录

课程模块(中)主要讲述课程详情部分

一、课程详情界面

1、创建课程详情界面

com.boxuegu.activity包中创建一个Java类命名为VideoListActivity。在res/layout文件夹下创建一个布局文件,命名为activity_video_list

2、导入界面图片 default_video_list_icon.pngvodeo_list_intro_icon.png

3、界面代码——activity_video_list.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:background="@android:color/white"
    android:orientation="vertical">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:background="@drawable/default_video_list_icon"/>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:orientation="horizontal">
        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:background="@drawable/video_list_intro_icon">
            <TextView
                android:layout_width="fill_parent"
                android:layout_height="46dp"
                android:id="@+id/tv_intro"
                android:layout_centerVertical="true"
                android:background="#30B4FF"
                android:gravity="center"
                android:text="简 介"
                android:textColor="#FFFFFF"
                android:textSize="20sp"/>
        </RelativeLayout>
        <View
            android:layout_width="1dp"
            android:layout_height="48dp"
            android:background="#C3C3C3"/>
        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:background="@drawable/video_list_intro_icon">
            <TextView
                android:layout_width="fill_parent"
                android:layout_height="46dp"
                android:id="@+id/tv_video"
                android:layout_centerVertical="true"
                android:background="#FFFFFF"
                android:gravity="center"
                android:text="视 频"
                android:textColor="#000000"
                android:textSize="20sp"/>
        </RelativeLayout>
    </LinearLayout>
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <ListView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/lv_video_list"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:divider="#E4E4E4"
            android:dividerHeight="1dp"
            android:scrollbars="none"
            android:visibility="gone"/>
        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/sv_chapter_intro">
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="horizontal">
                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:id="@+id/tv_chapter_intro"
                    android:lineSpacingMultiplier="1.5"
                    android:padding="10dp"
                    android:text="wordpress简介"
                    android:textColor="@android:color/black"
                    android:textSize="14sp"/>
            </LinearLayout>
        </ScrollView>
    </RelativeLayout>

</LinearLayout>

二、课程详情界面Item

1、创建课程详情界面item

res/layout文件夹下创建一个布局文件,命名为video_list_item。导入所需图片 course_bar_icon.png

2、界面代码——video_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:gravity="center_vertical"
    android:paddingBottom="15dp"
    android:paddingTop="15dp">
    <ImageView
        android:id="@+id/iv_left_icon"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:src="@drawable/course_bar_icon" />
    <TextView
        android:id="@+id/tv_video_title"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginLeft="10dp"
        android:gravity="center_vertical"
        android:textColor="#333333"
        android:textSize="14sp"/>
</LinearLayout>

三、创建VideoBean

com.boxuegu.bean包中创建一个VideoBean类,用来创建视频的所有属性。
package com.boxuegu.bean;

public class VideoBean {
    public int chapterId;       //章节ID
    public int videoId;			//视频ID
    public String title;		//章节标题
    public String secondTitle;	//视频标题
    public String videoPath;	//视频播放地址
}

四、课程界面Adapter

com.boxuegu.adapter包中创建一个VideoListAdapter类。代码如下:
package com.boxuegu.adapter;

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.ImageView;
import android.widget.TextView;
import java.util.List;
import com.boxuegu.R;
import com.boxuegu.bean.VideoBean;

//列表
public class VideoListAdapter extends BaseAdapter{

    private Context mContext;
    private List<VideoBean> vbl;  //视频列表数据
    private int selectedPosition = -1;  //点击时选中的位置
    private OnSelectListener onSelectListener;
    public VideoListAdapter(Context context,OnSelectListener onSelectListener){
        this.mContext = context;
        this.onSelectListener = onSelectListener;
    }

    public void setSelectedPosition(int position){
        selectedPosition = position;
    }

    //设置数据更新界面
    public void setData(List<VideoBean> vbl){
        this.vbl = vbl;
        notifyDataSetChanged();
    }

    //获取Item的总数
    @Override
    public int getCount() {
        return vbl == null ? 0 : vbl.size();
    }

  //根据position得到item对应的对象
    @Override
    public VideoBean getItem(int position) {
        return vbl == null ? null : vbl.get(position);
    }

    //根据position得到item对应的ID
    @Override
    public long getItemId(int position) {
        return position;
    }

    //得到对应position的item视图
    @Override
    public View getView(final int position, View view, ViewGroup viewGroup) {
        final ViewHolder vh;
        if (view == null){
            vh = new ViewHolder();
            view = LayoutInflater.from(mContext).inflate(
                    R.layout.video_list_item,null
            );
            vh.tv_title = (TextView) view.findViewById(R.id.tv_video_title);
            vh.iv_icon = (ImageView) view.findViewById(R.id.iv_left_icon);
            view.setTag(vh);
        }else {
            vh = (ViewHolder) view.getTag();
        }
        final VideoBean bean = getItem(position);
        vh.iv_icon.setImageResource(R.drawable.course_bar_icon);
        vh.tv_title.setTextColor(Color.parseColor("#333333"));
        if (bean!=null){
            vh.tv_title.setText(bean.secondTitle);
            //设置选中效果
            if (selectedPosition == position){
                vh.iv_icon.setImageResource(R.drawable.course_intro_icon);
                vh.tv_title.setTextColor(Color.parseColor("#009958"));

            }else {
                vh.iv_icon.setImageResource(R.drawable.course_bar_icon);
                vh.tv_title.setTextColor(Color.parseColor("#333333"));
            }
        }
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (bean == null)
                    return;
                //播放视频
                onSelectListener.onSelect(position,vh.iv_icon);
            }
        });
        return view;
    }

    class ViewHolder{
        public TextView tv_title;
        public ImageView iv_icon;
    }

    //创建接口,传递position和ImageView
    public interface OnSelectListener{
        void onSelect(int position,ImageView iv);
    }
}

五、视频列表数据的存放

1、Eclipse新建json文件,并改变文件的编码。

assets文件夹中右键,选择new,点击file

image

文件名输入data.json

image

由于默认的编码会导致软件运行以后中文出现乱码。在data.json文件里面,使用Alt+Enter快捷键弹出修改编码的对话框,编码方式选择UTF-8即可。

image

2、data.json代码如下:


[
 {
  "chapterId": 1,
  "videoId": "1",
  "title": "第1章 博客(网站)简介",
  "secondTitle": "什么是博客",
  "videoPath": "video11.mp4"
 },
 {
  "chapterId": 1,
  "videoId": "2",
  "title": "第1章 博客(网站)简介",
  "secondTitle": "网站与博客的关系",
  "videoPath": "beyond.mp4"
 },
 {
  "chapterId": 2,
  "videoId": "1",
  "title": "第2章 Linux系统简介",
  "secondTitle": "认识Linux",
  "videoPath": ""
 },
 {
  "chapterId": 2,
  "videoId": "2",
  "title": "第2章 Linux系统简介",
  "secondTitle": "CentOS 7简单操作",
  "videoPath": ""
 },
 {
  "chapterId": 3,
  "videoId": "1",
  "title": "第3章  WordPress简介",
  "secondTitle": "动态博客系统",
  "videoPath": ""
 },
 {
  "chapterId": 3,
  "videoId": "2",
  "title": "第3章 WordPress简介",
  "secondTitle": "WordPress系统",
  "videoPath": ""
 },
 {
  "chapterId": 4,
  "videoId": "1",
  "title": "第4章 安装MySQL数据库",
  "secondTitle": "MySQL数据库简介",
  "videoPath": ""
 },
 {
  "chapterId": 4,
  "videoId": "2",
  "title": "第4章 安装MySQL数据库",
  "secondTitle": "安装MySQL数据库",
  "videoPath": ""
 },
 {
  "chapterId": 5,
  "videoId": "1",
  "title": "第5章 数据存储服务器",
  "secondTitle": "常见的服务器",
  "videoPath": ""
 },
 {
  "chapterId": 5,
  "videoId": "2",
  "title": "第5章 数据存储服务器",
  "secondTitle": "Nginx的安装",
  "videoPath": ""
 },
 {
  "chapterId": 6,
  "videoId": "1",
  "title": "第6章 安装PHP环境",
  "secondTitle": "PHP语法简介",
  "videoPath": ""
 },
 {
  "chapterId": 6,
  "videoId": "2",
  "title": "第6章 安装PHP环境",
  "secondTitle": "安装PHP",
  "videoPath": ""
 },
 {
  "chapterId": 7,
  "videoId": "1",
  "title": "第7章 云服务器的购买",
  "secondTitle": "购买云服务器",
  "videoPath": ""
 },
 {
  "chapterId": 7,
  "videoId": "2",
  "title": "第7章 云服务器的购买",
  "secondTitle": "云服务器的简单配置",
  "videoPath": ""
 },
 {
  "chapterId": 8,
  "videoId": "1",
  "title": "第8章 域名购买及备案",
  "secondTitle": "购买域名",
  "videoPath": ""
 },
 {
  "chapterId": 8,
  "videoId": "2",
  "title": "第8章 域名购买及备案",
  "secondTitle": "域名备案",
  "videoPath": ""
 },
 {
  "chapterId": 9,
  "videoId": "1",
  "title": "第9章 安装WordPress",
  "secondTitle": "安装前准备",
  "videoPath": ""
 },
 {
  "chapterId": 9,
  "videoId": "2",
  "title": "第9章 安装WordPress",
  "secondTitle": "安装WordPress",
  "videoPath": ""
 },
 {
  "chapterId": 10,
  "videoId": "1",
  "title": "第10章 WordPress简单设置",
  "secondTitle": "更换博客主题",
  "videoPath": ""
 },
 {
  "chapterId": 10,
  "videoId": "2",
  "title": "第10章 WordPress简单设置",
  "secondTitle": "博客基本布局设置",
  "videoPath": ""
 }
]

六、课程详情界面逻辑代码

1、界面代码——VideoListActivity.java

package com.boxuegu.activity;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import com.boxuegu.R;
import com.boxuegu.adapter.VideoListAdapter;
import com.boxuegu.bean.VideoBean;
import com.boxuegu.utils.AnalysisUtils;
import com.boxuegu.utils.DBUtils;

public class VideoListActivity extends AppCompatActivity implements View.OnClickListener {

    private String intro;
    private int chapterId;
    private DBUtils db;
    private ArrayList<VideoBean> videoList;
    private TextView tv_intro;
    private TextView tv_video;
    private ListView lv_video_list;
    private TextView tv_chapter_intro;
    private ScrollView sv_chapter_intro;
    private VideoListAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_list);
        //设置界面为视频
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        //从课程界面传过来的章节ID
        chapterId = getIntent().getIntExtra("id", 0);
        //从课程界面传过来的章节简介
        intro = getIntent().getStringExtra("intro");
        db = DBUtils.getInstance(VideoListActivity.this);
        initData();
        initView();

    }

    //初始化界面UI控件
    private void initView() {
        tv_intro = (TextView) findViewById(R.id.tv_intro);
        tv_video = (TextView) findViewById(R.id.tv_video);
        lv_video_list = (ListView) findViewById(R.id.lv_video_list);
        tv_chapter_intro = (TextView) findViewById(R.id.tv_chapter_intro);
        sv_chapter_intro = (ScrollView)findViewById(R.id.sv_chapter_intro);
        adapter = new VideoListAdapter(this, new VideoListAdapter.OnSelectListener() {
            @Override
            public void onSelect(int position, ImageView iv) {
                adapter.setSelectedPosition(position); //设置适配器的选中项
                VideoBean bean = videoList.get(position);
                String videoPath = bean.videoPath;
                //notifyDataSetChanged刷新UI
                adapter.notifyDataSetChanged();
                if (TextUtils.isEmpty(videoPath)){
                    Toast.makeText(VideoListActivity.this,"本地没有此视频,暂时无法播放",Toast.LENGTH_SHORT).show();
                    return;
                }else {
                    //判断用户是否登录,若登录则把视频添加到记录中
                    if (readLoginStatus()){
                        String userName = AnalysisUtils.readLoginUserName(VideoListActivity.this);
                        db.saveVideoPlayList(videoList.get(position),userName);

                    }
                    //跳转到视频播放界面

                }
            }
        });
        lv_video_list.setAdapter(adapter);
        tv_intro.setOnClickListener(this);
        tv_video.setOnClickListener(this);
        adapter.setData(videoList);
        tv_chapter_intro.setText(intro);
        tv_intro.setBackgroundColor(Color.parseColor("#30B4FF"));
        tv_video.setBackgroundColor(Color.parseColor("#FFFFFF"));
        tv_intro.setTextColor(Color.parseColor("#FFFFFF"));
        tv_video.setTextColor(Color.parseColor("#000000"));


    }
    /**
     * 设置视频列表本地数据
     */
    private void initData() {
        //多个视频,用jsonArray
        JSONArray jsonArray;
        InputStream is = null;
        try {
            is = getResources().getAssets().open("data.json");
            jsonArray = new JSONArray(read(is));
            videoList = new ArrayList<VideoBean>();
            for (int i = 0;i < jsonArray.length();i++){
                VideoBean bean = new VideoBean();
                JSONObject jsonObj = jsonArray.getJSONObject(i);
                if(jsonObj.getInt("chapterId") == chapterId){
                    bean.chapterId = jsonObj.getInt("chapterId");
                    bean.videoId = Integer.parseInt(jsonObj.getString("videoId"));
                    bean.title = jsonObj.getString("title");
                    bean.secondTitle = jsonObj.getString("secondTitle");
                    bean.videoPath = jsonObj.getString("videoPath");
                    videoList.add(bean);
                }
                bean = null;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
/*
    *读取数据流,参数in就是数据流,把输入流转换成字符串
     */

    private String read(InputStream in) {
        BufferedReader reader = null;
        StringBuilder sb = null;
        String line = null;
        try {
            sb = new StringBuilder(); //实例化一个StringBulider对象
            //InoutStreamReader把in字节流转换成字符流
            reader = new BufferedReader(new InputStreamReader(in));
            while ((line = reader.readLine()) != null) {
                sb.append(line);
                sb.append("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

    /**
     * 从SharedPreferences读取登录状态
     */

    private boolean readLoginStatus() {
        SharedPreferences sp = getSharedPreferences("loginInfo", Context.MODE_PRIVATE);
        boolean isLogin = sp.getBoolean("isLogin",false);
        return isLogin;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (data!=null){
            //
            int position = data.getIntExtra("position",0);
            adapter.setSelectedPosition(position);
            //
            lv_video_list.setVisibility(View.VISIBLE);
            sv_chapter_intro.setVisibility(View.GONE);
            tv_intro.setBackgroundColor(Color.parseColor("#FFFFFF"));
            tv_video.setBackgroundColor(Color.parseColor("#30B4FF"));
            tv_intro.setTextColor(Color.parseColor("#000000"));
            tv_video.setTextColor(Color.parseColor("#FFFFFF"));

        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.tv_intro:  //简介
                lv_video_list.setVisibility(View.GONE);
                sv_chapter_intro.setVisibility(View.VISIBLE);
                tv_intro.setBackgroundColor(Color.parseColor("#30B4FF"));
                tv_video.setBackgroundColor(Color.parseColor("#FFFFFF"));
                tv_intro.setTextColor(Color.parseColor("#FFFFFF"));
                tv_video.setTextColor(Color.parseColor("#000000"));
                break; 
            case R.id.tv_video:  //视频
                lv_video_list.setVisibility(View.VISIBLE);
                sv_chapter_intro.setVisibility(View.GONE);
                tv_intro.setBackgroundColor(Color.parseColor("#FFFFFF"));
                tv_intro.setTextColor(Color.parseColor("#000000"));
                tv_video.setBackgroundColor(Color.parseColor("#30B4FF"));
                tv_video.setTextColor(Color.parseColor("#FFFFFF"));
                break;
            default:
                break;
        }
    }
}

2、修改代码

(1)、找到SQLiteHelper.java文件,在 public static final String U_USERINFO = "userinfo"; 下方添加如下代码:
public static final String U_VIDEO_PLAY_LIST = "videoplaylist";  //视频播放列表
(2)、找到SQLiteHelper.java文件,在onCreate()方法里面添加如下代码:
//创建视频播放记录
        db.execSQL("CREATE TABLE IF NOT EXISTS " + U_VIDEO_PLAY_LIST + "( " +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                + "userName VARCHAR,"//用户名
                + "chapterId INT," //章节id
                + "videoId INT,"//小节id
                + "videoPath VARCHAR,"
                + "title VARCHAR,"  //章节名字
                + "secondTitle VARCHAR" // 视频名字
                + ")");
(3)、找到SQLiteHelper.java文件,在onUpgrade()方法里面的onCreate(db);语句前添加如下代码:
db.execSQL("DROP TABLE IF NOT EXISTS " + U_VIDEO_PLAY_LIST);
(4)、找到DBUtils.java文件,添加如下代码:
 //保存视频播放记录
    public void saveVideoPlayList(VideoBean bean, String userName) {
        //判断如果里面已经有此记录则需要先删除再重新存放
        if (hasVideoPlay(bean.chapterId, bean.videoId, userName)) {
            boolean isDelete = delVideoPlay(bean.chapterId, bean.videoId, userName);
            if (!isDelete) {
                //没有删除成功
                return;
            }
        }
        ContentValues cv = new ContentValues();
        cv.put("userName", userName);
        cv.put("chapterId", bean.chapterId);
        cv.put("videoId", bean.videoId);
        cv.put("videoPath", bean.videoPath);
        cv.put("title", bean.title);
        cv.put("secondTitle", bean.secondTitle);
        db.insert(SQLiteHelper.U_VIDEO_PLAY_LIST, null, cv);

    }

    /**
     * 删除已经存在的是视屏记录
     * @param chapterId
     * @param videoId
     * @param userName
     * @return
     */

    public boolean delVideoPlay(int chapterId, int videoId, String userName) {
        boolean delSuccess = false;
        int row = db.delete(SQLiteHelper.U_VIDEO_PLAY_LIST, " chapterId=? AND videoId=? AND userName=?",
                new String[]{chapterId + "", videoId + "", userName});
        if (row > 0) {
            delSuccess = true;
        }

        return delSuccess;
    }
    /**
     * 判断视频记录是否存在
     * @param chapterId
     * @param videoId
     * @param userName
     * @return
     */
    public boolean hasVideoPlay(int chapterId, int videoId, String userName) {
        boolean hasVideo = false;
        String sql = "SELECT * FROM " + SQLiteHelper.U_VIDEO_PLAY_LIST + " WHERE chapterId=? AND videoId=? AND userName =?";
        Cursor cursor = db.rawQuery(sql, new String[]{ chapterId + "", videoId + "", userName});
        if (cursor.moveToFirst()) {
            hasVideo = true;
        }
        cursor.close();
        return hasVideo;
    }
(5)、找到CourseAdapter.java文件,在两处注释//跳转到课程详情界面分别添加以下代码:
 Intent intent = new Intent(mContext, VideoListActivity.class);
intent.putExtra("id",bean.id);
intent.putExtra("intro",bean.intro);
mContext.startActivity(intent);

七、运行效果

在这里插入图片描述

Android项目实战系列—基于博学谷 开源地址

image               
image


http://www.niftyadmin.cn/n/3649618.html

相关文章

如何在JavaScript中使用解构分配

JavaScript provides you with the ability to destructure objects and assign the individual units in one take. This allows you to get to the point of what you want to do and keep things clean. JavaScript使您能够分解对象并一次性完成分配各个单元的功能。 这使您…

Java基础---集合框架二(ArrayList 接口)

2015-4-16 一、List集合 1、List集合特有方法 特有方法&#xff1a; voidadd(int index, E element) &#xff1a; 在当前集合中指定位置 添加给定的元素 Objectget(int index) 返回集合中指定位置的元素。 intindexOf(Object o)返回此集合中第一次出现的指定元素的索引&…

Java基础---IO流三(字节流 字符流)

2015-04-23 一、转换流&#xff08;IO流续&#xff09; 1、编码表概述 由字符及其对应的数值组成的一张表 编码 把看得懂的变成看不懂的 解码 把看不懂的变成看得懂的 常见的编码表 ASCII&#xff1a;用7位来表示一个数据 ISO-8859-1&#xff1a;在西欧使用&#xff0c;…

Android项目实战系列—基于博学谷(七)课程模块(下)

由于这个模块内容较多,分为上、中、下 三篇博客分别来讲述&#xff0c;请耐心阅读。 课程模块分为四个部分 课程列表 课程详情 视频播放 播放记录 课程模块&#xff08;下&#xff09;主要讲述视频播放和播放记录两个部分 一、视频播放 1、视频播放界面 &#xff08;1&#…

angular id标记_使用传单在Angular中构建地图,第2部分:标记服务

angular id标记In my last post, we set up our environment to create a basic map using Leaflet and Angular. Let’s go a bit further now and add markers to our map. 在上一篇文章中 &#xff0c;我们设置了环境以使用Leaflet和Angular创建基本地图。 现在让我们再走一…

Java高新技术---反射动态代理

2015-04-25 一、反射 1、概述 JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意一个方法和属 性&#xff1b;这种动态获取的信息以及动态调用对象的方…

[xmlpull]XmlPull常见错误

[xmlpull]XmlPull常见错误编写者日期关键词郑昀ultrapower2005-9-28Xmlpull kxml java Xmlpull官方站点&#xff1a;http://www.xmlpull.org/优点&#xff1a;不必等整个文档解析完成&#xff0c;部分求值结果早就可以开始反馈给用户。What Is It?XmlPull project is dedicate…

C#实战系列—学生信息管理系统(一)项目展示

最近在整理自己电脑上的学习资料&#xff0c;突然发现大二时小组一起做的C#项目——学生信息管理系统。就想运行起来玩玩。可是现在主机里面都是一些开发Android和Java的软件。visual studio 2010也早就卸载了。不过想到我们开发的这个系统在Windows 10系统上的兼容性不太好。所…