- 浏览: 1935590 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
龙宝宝吱吱:
我现在知道是在部署的项目里找,可是找不到啊,一般这个文件会在什 ...
webservice浏览器远程调用测试 -
龙宝宝吱吱:
这个webconfig文件在哪里啊,大神
webservice浏览器远程调用测试 -
yuer1218:
正在学习这块,能把源码发我一份吗,12045464@qq.co ...
Android时钟的widget【安卓进化三十七】 -
hongshanguo:
为嘛没有任务管理器的,求案例啊
近百android程序源码贡献 -
难得糊涂CN2010:
最近一个项目要用到widget,可以送下源码不?dz.bita ...
Android时钟的widget【安卓进化三十七】
AndroidICS4.0---->LockScreen锁屏流程【Android源码解析九】
先来说说LockScreen分类;
一、无锁屏;
二、锁屏:
1、UnLockScreen:
图案锁、 PIN锁, 密码锁;
2、LockScreen:
波纹锁;
转载请表明出处:http://blog.csdn.net/wdaming1986/article/details/7753206
有图有真相------>
接着我们来看看LockScreen的时序图:
综上所述:
1、createUnlockScreenFor()方法创建的是UnLockScreen界面,代码如下:
View createUnlockScreenFor(UnlockMode unlockMode) { View unlockView = null; if (DEBUG) Log.d(TAG, "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback); if (unlockMode == UnlockMode.Pattern) { PatternUnlockScreen view = new PatternUnlockScreen( mContext, mConfiguration, mLockPatternUtils, mUpdateMonitor, mKeyguardScreenCallback, mUpdateMonitor.getFailedAttempts()); view.setEnableFallback(mEnableFallback); unlockView = view; } else if (unlockMode == UnlockMode.SimPuk) { unlockView = new SimPukUnlockScreen( mContext, mConfiguration, mUpdateMonitor, mKeyguardScreenCallback, mLockPatternUtils, MSimTelephonyManager.getDefault().getDefaultSubscription()); } else if (unlockMode == UnlockMode.SimPin) { unlockView = new SimUnlockScreen( mContext, mConfiguration, mUpdateMonitor, mKeyguardScreenCallback, mLockPatternUtils); } else if (unlockMode == UnlockMode.Account) { try { unlockView = new AccountUnlockScreen( mContext, mConfiguration, mUpdateMonitor, mKeyguardScreenCallback, mLockPatternUtils); } catch (IllegalStateException e) { Log.i(TAG, "Couldn't instantiate AccountUnlockScreen" + " (IAccountsService isn't available)"); // TODO: Need a more general way to provide a // platform-specific fallback UI here. // For now, if we can't display the account login // unlock UI, just bring back the regular "Pattern" unlock mode. // (We do this by simply returning a regular UnlockScreen // here. This means that the user will still see the // regular pattern unlock UI, regardless of the value of // mUnlockScreenMode or whether or not we're in the // "permanently locked" state.) return createUnlockScreenFor(UnlockMode.Pattern); } } else if (unlockMode == UnlockMode.Password) { unlockView = new PasswordUnlockScreen( mContext, mConfiguration, mLockPatternUtils, mUpdateMonitor, mKeyguardScreenCallback); } else { throw new IllegalArgumentException("unknown unlock mode " + unlockMode); } initializeTransportControlView(unlockView); initializeFaceLockAreaView(unlockView); // Only shows view if FaceLock is enabled mUnlockScreenMode = unlockMode; return unlockView; }
2、createLockScreen()就是创建LockScreen界面:
View createLockScreen() { /*View lockView = new LockScreen( mContext, mConfiguration, mLockPatternUtils, mUpdateMonitor, mKeyguardScreenCallback); initializeTransportControlView(lockView); return lockView;*/ long lockscreenType = 0; try{ lockscreenType = android.provider.Settings.Secure. getLong(mContext.getContentResolver(), "lockscreen.disabled"); }catch(Exception e){ e.printStackTrace(); } View lockView = null; lockView = new LockScreen( mContext, mConfiguration, mLockPatternUtils, mUpdateMonitor, mKeyguardScreenCallback); initializeTransportControlView(lockView); return lockView; }
我们来看看锁屏界面的流程:
step 1:创建LockScreen.java类——>先看看构造函数:
LockScreen(Context context, Configuration configuration, LockPatternUtils lockPatternUtils, KeyguardUpdateMonitor updateMonitor, KeyguardScreenCallback callback) { super(context); mLockPatternUtils = lockPatternUtils; mUpdateMonitor = updateMonitor; mCallback = callback; mEnableMenuKeyInLockScreen = shouldEnableMenuKey(); mCreationOrientation = configuration.orientation; mKeyboardHidden = configuration.hardKeyboardHidden; if (LockPatternKeyguardView.DEBUG_CONFIGURATION) { Log.v(TAG, "***** CREATING LOCK SCREEN", new RuntimeException()); Log.v(TAG, "Cur orient=" + mCreationOrientation + " res orient=" + context.getResources().getConfiguration().orientation); } final LayoutInflater inflater = LayoutInflater.from(context); if (DBG) Log.v(TAG, "Creation orientation = " + mCreationOrientation); if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) { inflater.inflate(R.layout.keyguard_screen_tab_unlock, this, true); } else { inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, this, true); } if (TelephonyManager.getDefault().isMultiSimEnabled()) { mStatusViewManager = new MSimKeyguardStatusViewManager(this, mUpdateMonitor, mLockPatternUtils, mCallback, false); } else { mStatusViewManager = new KeyguardStatusViewManager(this, mUpdateMonitor, mLockPatternUtils, mCallback, false); } setFocusable(true); setFocusableInTouchMode(true); setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); // modify by wangxianming in 2012-06-22 if (mAudioManager != null) { mSilentMode = isSilentMode(); } mUnlockWidget = findViewById(R.id.unlock_widget); if (mUnlockWidget instanceof SlidingTab) { SlidingTab slidingTabView = (SlidingTab) mUnlockWidget; slidingTabView.setHoldAfterTrigger(true, false); slidingTabView.setLeftHintText(R.string.lockscreen_unlock_label); slidingTabView.setLeftTabResources( R.drawable.ic_jog_dial_unlock, R.drawable.jog_tab_target_green, R.drawable.jog_tab_bar_left_unlock, R.drawable.jog_tab_left_unlock); SlidingTabMethods slidingTabMethods = new SlidingTabMethods(slidingTabView); slidingTabView.setOnTriggerListener(slidingTabMethods); mUnlockWidgetMethods = slidingTabMethods; } else if (mUnlockWidget instanceof WaveView) { WaveView waveView = (WaveView) mUnlockWidget; WaveViewMethods waveViewMethods = new WaveViewMethods(waveView); waveView.setOnTriggerListener(waveViewMethods); mUnlockWidgetMethods = waveViewMethods; } else if (mUnlockWidget instanceof MultiWaveView) { MultiWaveView multiWaveView = (MultiWaveView) mUnlockWidget; MultiWaveViewMethods multiWaveViewMethods = new MultiWaveViewMethods(multiWaveView); multiWaveView.setOnTriggerListener(multiWaveViewMethods); mUnlockWidgetMethods = multiWaveViewMethods; } else { throw new IllegalStateException("Unrecognized unlock widget: " + mUnlockWidget); } // Update widget with initial ring state mUnlockWidgetMethods.updateResources(); if (DBG) Log.v(TAG, "*** LockScreen accel is " + (mUnlockWidget.isHardwareAccelerated() ? "on":"off")); }
Step 2:在Step 1步骤中根据横竖屏来加载横竖屏的布局:
if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) { inflater.inflate(R.layout.keyguard_screen_tab_unlock, this, true); } else { inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, this, true); }
Step 3:来看看竖屏的布局文件的代码:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal"> <!-- 锁屏界面加载数字时钟 --> <com.android.internal.widget.DigitalClock android:id="@+id/time" android:layout_marginTop="@dimen/keyguard_lockscreen_status_line_clockfont_top_margin" android:layout_marginBottom="12dip" android:layout_marginRight="@dimen/keyguard_lockscreen_status_line_font_right_margin" android:layout_gravity="right"> <!-- Because we can't have multi-tone fonts, we render two TextViews, one on top of the other. Hence the redundant layout... --> <TextView android:id="@+id/timeDisplayBackground" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:ellipsize="none" android:textSize="@dimen/keyguard_lockscreen_clock_font_size" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_marginBottom="6dip" android:textColor="@color/lockscreen_clock_background" /> <TextView android:id="@+id/timeDisplayForeground" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:ellipsize="none" android:textSize="@dimen/keyguard_lockscreen_clock_font_size" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_marginBottom="6dip" android:textColor="@color/lockscreen_clock_foreground" android:layout_alignLeft="@id/timeDisplayBackground" android:layout_alignTop="@id/timeDisplayBackground" /> </com.android.internal.widget.DigitalClock> <LinearLayout android:orientation="horizontal" android:layout_gravity="right" android:layout_marginRight="@dimen/keyguard_lockscreen_status_line_font_right_margin"> <!-- 锁屏界面加载日期 --> <TextView android:id="@+id/date" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:ellipsize="marquee" android:textAppearance="?android:attr/textAppearanceMedium" android:textSize="@dimen/keyguard_lockscreen_status_line_font_size" /> <!-- 锁屏界面加载闹钟状态 --> <TextView android:id="@+id/alarm_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="16dip" android:singleLine="true" android:ellipsize="marquee" android:textAppearance="?android:attr/textAppearanceMedium" android:textSize="@dimen/keyguard_lockscreen_status_line_font_size" android:drawablePadding="4dip" /> </LinearLayout> <!-- 锁屏界面加载充电状态 --> <TextView android:id="@+id/status1" android:layout_gravity="right" android:layout_marginRight="@dimen/keyguard_lockscreen_status_line_font_right_margin" android:singleLine="true" android:ellipsize="marquee" android:textAppearance="?android:attr/textAppearanceMedium" android:textSize="@dimen/keyguard_lockscreen_status_line_font_size" android:drawablePadding="4dip" /> <Space android:layout_gravity="fill" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="302dip"> <!-- 锁屏界面加载波纹的锁屏 --> <com.android.internal.widget.multiwaveview.MultiWaveView android:id="@+id/unlock_widget" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentBottom="true" android:targetDrawables="@array/lockscreen_targets_with_camera" android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera" android:directionDescriptions="@array/lockscreen_direction_descriptions" android:handleDrawable="@drawable/ic_lockscreen_handle" android:waveDrawable="@drawable/ic_lockscreen_outerring" android:outerRadius="@dimen/multiwaveview_target_placement_radius" android:snapMargin="@dimen/multiwaveview_snap_margin" android:hitRadius="@dimen/multiwaveview_hit_radius" android:rightChevronDrawable="@drawable/ic_lockscreen_chevron_right" android:horizontalOffset="0dip" android:verticalOffset="60dip" android:feedbackCount="3" android:vibrationDuration="20" /> <!-- 锁屏界面加载运营商状态 --> <TextView android:id="@+id/carrier" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="12dip" android:gravity="center_horizontal" android:singleLine="true" android:ellipsize="marquee" android:textAppearance="?android:attr/textAppearanceMedium" android:textSize="@dimen/keyguard_lockscreen_status_line_font_size" android:textColor="?android:attr/textColorSecondary" /> </RelativeLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" style="?android:attr/buttonBarStyle" android:gravity="center" android:weightSum="2"> <!-- 锁屏界面加载紧急拨号按钮 --> <Button android:id="@+id/emergencyCallButton" android:layout_gravity="center_horizontal" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" style="?android:attr/buttonBarButtonStyle" android:textSize="@dimen/keyguard_lockscreen_status_line_font_size" android:text="@*android:string/lockscreen_emergency_call" android:drawableLeft="@*android:drawable/lockscreen_emergency_button" android:drawablePadding="0dip" android:visibility="gone" /> </LinearLayout> </GridLayout>
Step 4:在Step 3中重点看com.android.internal.widget.multiwaveview.MultiWaveView这个自定义的view,这个view是处理ICS4.0锁屏的拖拽的功能,具体代码如下:
public MultiWaveView(Context context, AttributeSet attrs) { super(context, attrs); Resources res = context.getResources(); 。。。 。。。 加载资源 。。。 。。。 }
通过onMeasure()来计算自定义view的大小:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int minimumWidth = getSuggestedMinimumWidth(); final int minimumHeight = getSuggestedMinimumHeight(); int viewWidth = resolveMeasured(widthMeasureSpec, minimumWidth); int viewHeight = resolveMeasured(heightMeasureSpec, minimumHeight); setMeasuredDimension(viewWidth, viewHeight); }
通过onLayout()来加载布局:
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); final int width = right - left; final int height = bottom - top; float newWaveCenterX = mHorizontalOffset + Math.max(width, mOuterRing.getWidth() ) / 2; float newWaveCenterY = mVerticalOffset + Math.max(height, mOuterRing.getHeight()) / 2; if (newWaveCenterX != mWaveCenterX || newWaveCenterY != mWaveCenterY) { if (mWaveCenterX == 0 && mWaveCenterY == 0) { performInitialLayout(newWaveCenterX, newWaveCenterY); } mWaveCenterX = newWaveCenterX; mWaveCenterY = newWaveCenterY; mOuterRing.setX(mWaveCenterX); mOuterRing.setY(Math.max(mWaveCenterY, mWaveCenterY)); updateTargetPositions(); } if (DEBUG) dump(); }
Step 5:来看看触摸屏幕时的事件处理onTouchEvent()代码如下:
@Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getAction(); boolean handled = false; switch (action) { case MotionEvent.ACTION_DOWN: handleDown(event); handled = true; break; case MotionEvent.ACTION_MOVE: handleMove(event); handled = true; break; case MotionEvent.ACTION_UP: handleMove(event); handleUp(event); handled = true; break; case MotionEvent.ACTION_CANCEL: handleMove(event); handled = true; break; } invalidate(); return handled ? true : super.onTouchEvent(event); }
通过handleMove()来处理移动事件:
private void handleMove(MotionEvent event) { if (!mDragging) { trySwitchToFirstTouchState(event); return; } int activeTarget = -1; final int historySize = event.getHistorySize(); for (int k = 0; k < historySize + 1; k++) { float x = k < historySize ? event.getHistoricalX(k) : event.getX(); float y = k < historySize ? event.getHistoricalY(k) : event.getY(); float tx = x - mWaveCenterX; float ty = y - mWaveCenterY; float touchRadius = (float) Math.sqrt(dist2(tx, ty)); final float scale = touchRadius > mOuterRadius ? mOuterRadius / touchRadius : 1.0f; float limitX = mWaveCenterX + tx * scale; float limitY = mWaveCenterY + ty * scale; boolean singleTarget = mTargetDrawables.size() == 1; if (singleTarget) { // Snap to outer ring if there's only one target float snapRadius = mOuterRadius - mSnapMargin; if (touchRadius > snapRadius) { activeTarget = 0; x = limitX; y = limitY; } } else { // If there's more than one target, snap to the closest one less than hitRadius away. float best = Float.MAX_VALUE; final float hitRadius2 = mHitRadius * mHitRadius; for (int i = 0; i < mTargetDrawables.size(); i++) { // Snap to the first target in range TargetDrawable target = mTargetDrawables.get(i); float dx = limitX - target.getX(); float dy = limitY - target.getY(); float dist2 = dx*dx + dy*dy; if (target.isValid() && dist2 < hitRadius2 && dist2 < best) { activeTarget = i; best = dist2; } } x = limitX; y = limitY; } if (activeTarget != -1) { switchToState(STATE_SNAP, x,y); float newX = singleTarget ? limitX : mTargetDrawables.get(activeTarget).getX(); float newY = singleTarget ? limitY : mTargetDrawables.get(activeTarget).getY(); moveHandleTo(newX, newY, false); TargetDrawable currentTarget = mTargetDrawables.get(activeTarget); if (currentTarget.hasState(TargetDrawable.STATE_FOCUSED)) { currentTarget.setState(TargetDrawable.STATE_FOCUSED); mHandleDrawable.setAlpha(0.0f); } } else { switchToState(STATE_TRACKING, x, y); moveHandleTo(x, y, false); mHandleDrawable.setAlpha(1.0f); } } // Draw handle outside parent's bounds invalidateGlobalRegion(mHandleDrawable); if (mActiveTarget != activeTarget && activeTarget != -1) { dispatchGrabbedEvent(activeTarget); if (AccessibilityManager.getInstance(mContext).isEnabled()) { String targetContentDescription = getTargetDescription(activeTarget); announceText(targetContentDescription); } } mActiveTarget = activeTarget; }
以上主要工作是绘制拖拽的参数以及绘制出来。通过invalidate()来主动刷屏幕;
在onDraw()方法中实现绘制图形,代码如下:
@Override protected void onDraw(Canvas canvas) { mOuterRing.draw(canvas); for (TargetDrawable target : mTargetDrawables) { if (target != null) { target.draw(canvas); } } for (TargetDrawable target : mChevronDrawables) { if (target != null) { target.draw(canvas); } } mHandleDrawable.draw(canvas); }
在handleMove()方法中——>trySwitchToFirstTouchState(event);——>switchToState()——>doFinish();
——>setGrabbedState() ————>mOnTriggerListener.onGrabbedStateChange(this, mGrabbedState);
设置回调。
Step 6:LockScreen.java中有个内部类,监听这个移动事件的状态,——> 代码如下:
class MultiWaveViewMethods implements MultiWaveView.OnTriggerListener, UnlockWidgetCommonMethods { private final MultiWaveView mMultiWaveView; private boolean mCameraDisabled; MultiWaveViewMethods(MultiWaveView multiWaveView) { mMultiWaveView = multiWaveView; final boolean cameraDisabled = mLockPatternUtils.getDevicePolicyManager() .getCameraDisabled(null); if (cameraDisabled) { Log.v(TAG, "Camera disabled by Device Policy"); mCameraDisabled = true; } else { // Camera is enabled if resource is initially defined for MultiWaveView // in the lockscreen layout file mCameraDisabled = mMultiWaveView.getTargetResourceId() != R.array.lockscreen_targets_with_camera; } } public void updateResources() { int resId; if (mCameraDisabled) { // Fall back to showing ring/silence if camera is disabled by DPM... resId = mSilentMode ? R.array.lockscreen_targets_when_silent : R.array.lockscreen_targets_when_soundon; } else { resId = R.array.lockscreen_targets_with_camera; } mMultiWaveView.setTargetResources(resId); } public void onGrabbed(View v, int handle) { } public void onReleased(View v, int handle) { } public void onTrigger(View v, int target) { if (target == 0 || target == 1) { // 0 = unlock/portrait, 1 = unlock/landscape mCallback.goToUnlockScreen(); } else if (target == 2 || target == 3) { // 2 = alt/portrait, 3 = alt/landscape if (!mCameraDisabled) { // Start the Camera Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); mCallback.goToUnlockScreen(); } else { toggleRingMode(); mUnlockWidgetMethods.updateResources(); mCallback.pokeWakelock(); } } } public void onGrabbedStateChange(View v, int handle) { // Don't poke the wake lock when returning to a state where the handle is // not grabbed since that can happen when the system (instead of the user) // cancels the grab. if (handle != MultiWaveView.OnTriggerListener.NO_HANDLE) { mCallback.pokeWakelock(); } } public View getView() { return mMultiWaveView; } public void reset(boolean animate) { mMultiWaveView.reset(animate); } public void ping() { mMultiWaveView.ping(); } }
重点看public void onTrigger()这个方法,用于处理拖拽启动那个activity,一个启动camera,一个正常解锁。
锁屏的大概这个流程就是这个样子了,大家应该会一目了然了。由于时间仓促,难免有点纰漏,希望大家指正错误,如有不解的地方,欢迎留言探讨!!!
相关推荐
一>、Android重启功能 在androidjava层执行shell命令来完成。但是笔者在开发测试中同样的代码发现用Eng编译出的版本可以重新启动,user版本不能完成重启,挂在关机那个界面。 /********************************...
标题中提到的“基于ARM的智能家居红外控制系统设计”,涉及的关键知识点集中在智能家居的系统设计、红外控制技术、ARM技术、Linux嵌入式系统以及Android设备的集成应用。 首先,智能家居(Smart Home)是利用现代...
基于springboot大学生就业信息管理系统源码数据库文档.zip
基于java的驾校收支管理可视化平台的开题报告
时间序列 原木 间隔5秒钟 20241120
毕业设计&课设_基于 Vue 的电影在线预订与管理系统:后台 Java(SSM)代码,为毕业设计项目.zip
基于springboot课件通中小学教学课件共享平台源码数据库文档.zip
基于java的网上购物商城的开题报告
Delphi人脸检测与识别Demo1fdef-main.zip
基于java的咖啡在线销售系统的开题报告
基于java的自助医疗服务系统的开题报告.docx
内容概要:本文档全面介绍了Visual Basic(VB)编程语言的基础知识和高级应用。首先概述了VB的基本特性和开发环境,随后详细讲述了VB的数据类型、变量、运算符、控制结构、数组、过程与函数、变量作用域等内容。接着介绍了窗体设计、控件使用、菜单与工具栏的设计,文件操作、数据库访问等关键知识点。最后讨论了VB的学习方法、发展历史及其在桌面应用、Web应用、数据库应用、游戏开发和自动化脚本编写等领域的广泛应用前景。 适合人群:初学者和中级程序员,尤其是希望快速掌握Windows桌面应用开发的人群。 使用场景及目标:①掌握VB的基础语法和开发环境;②学会使用VB创建复杂的用户界面和功能完整的应用程序;③理解数据库操作、文件管理和网络编程等高级主题。 其他说明:Visual Basic是一种简单易学且功能强大的编程语言,尤其适合用于开发Windows桌面应用。文中不仅覆盖了基础知识,还包括了大量的实用案例和技术细节,帮助读者快速提升编程技能。
基于java的疫情期间高校防控系统开题报告.docx
基于springboot+vue社区老年人帮扶系统源码数据库文档.zip
基于java的超市商品管理系统的开题报告.docx
基于SpringBoot房屋买卖平台源码数据库文档.zip
xdu限通院23微处理器系统与应用大作业(两只老虎),适应于汇编语言keil软件,
<项目介绍> - 新闻类网站系统,基于SSM(Spring、Spring MVC、MyBatis)+MySQL开发,高分成品毕业设计,附带往届论文 - 不懂运行,下载完可以私聊问,可远程教学 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
基于java的学生网上请假系统的开题报告.docx
社会经济繁荣发展的今天,电子商务得到了飞速发展,网上交易越来越彰显出其独特的优越性,在人们的日常生活中,出现了各种类型的交易网站。其中一个就是车辆易主交易网站,它是一个服务于用户买卖二手车辆的交易网站,为用户提供了平等互利、方便快捷的网上交易平台,通过这一类型的网站,用户可自由出售和购买车辆。 本课题主要根据车辆本身的特性,充分发挥互联网的特点与优势,构建一个以二手车辆为商品、基于互联网平台的车辆易主业务交易管理系统,并根据车辆易主业务交易管理系统的应用需求,进行需求分析,进而对网站系统作规划设计。采用IDEA为运行平台,以SSH为框架,运用HTML语言、JSP技术、MySql数据库、JSP与后台数据库链接等关键技术建设二手车网上交易系统,构建车辆易主交易系统的会员注册与登录,网站首页展示、用户发布商品车辆,用户求购商品车辆,分页浏览、购物系统、用户后台管理、管理员用户后台管理等功能,并使这些功能得以实现并更好为用户服务。网站整体构建完成且测试成功后,用户可以进入网站进行注册、登录,登录后,用户可以在网站上发布自己的闲置车辆或者寻找想要购买的车辆,还可以收藏车辆,管理发布和收藏的车辆,