您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關JavaMe開發中什么是MVC設計模式,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
【問題描述】介紹設計模式的文章和書很多,但只有使用時,才能理解設計模式的妙處。對UIController作出解釋,一則將自己理解的MVC設計模式,結合實例,與大家交流學習。
【理論】什么是MVC?
MVC就是模型(model)、視圖(view)和控制(control)。什么是模型呢?本例中,模型就是對數據使用時的封裝。視圖很容易理解,那就是顯示內容的具體表示。控制呢?有很多人對視圖和控制分不清。在本例中,控制包含視圖控制器以及方法的封裝。
【實例】
1、先看工程結構,如圖1所示。
圖1 工程結構
工程中將用戶數據單獨封裝,作為model。供控制器和視圖調用。將顯示頁面單獨封裝,作為視圖。將視圖控制器UIController和常用方法封裝為util。UIController就是控制。
2、UML圖(后續更新時補充)
先看代碼,再分析工作機理
【代碼清單】
MainMidlet.java
package com.token.midlet; import java.io.IOException; import javax.microedition.lcdui.*; import javax.microedition.midlet.MIDlet; import javax.microedition.midlet.MIDletStateChangeException; import com.token.util.UIController; public class MainMidlet extends MIDlet { private Display display; private static UIController controller; public MainMidlet() { // TODO Auto-generated constructor stub super(); display=Display.getDisplay(this); } /* (non-Javadoc) * @see javax.microedition.midlet.MIDlet#pauseApp() */ protected void startApp() throws MIDletStateChangeException { controller=new UIController(this); try { controller.init(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }//初始化RecordStore } /* (non-Javadoc) * @see javax.microedition.midlet.MIDlet#pauseApp() */ protected void pauseApp() { this.notifyPaused(); } /* (non-Javadoc) * @see javax.microedition.midlet.MIDlet#destroyApp(boolean) */ protected void destroyApp(boolean arg0) throws MIDletStateChangeException { controller=null; } public void setCurrent(Displayable disp){ display.setCurrent(disp); } public void setCurrent(Alert alert, Displayable disp){ display.setCurrent(alert, disp); } public Displayable getCurrent(){ return display.getCurrent(); } public void exit(boolean arg0){ try{ destroyApp(arg0); notifyDestroyed(); }catch(MIDletStateChangeException e){ // } } }
模型(Model)
UserDataItem.java
package com.token.model; import com.token.util.StringDealMethod; public class UserDataItem { private int id; public String name = null; public String passwd = null; public UserDataItem(String name,String passwd) { this.name = name; this.passwd = passwd; } public UserDataItem(int id,byte[] data){ this.id=id; String temp=new String(data); String temp_sub[] = StringDealMethod.split(temp, ","); this.name = temp_sub[0]; this.passwd = temp_sub[1]; } public int getId(){ return id; } public void setId(int id){ this.id=id; } public String getName(){ return name; } public void setName(String name){ this.name = name; } public String getPasswd(){ return passwd; } public void setPasswd(String passwd){ this.passwd = passwd; } public byte[] getBytes(){ String temp=null; if(name==null||passwd==null){ return null; }else{ temp=name+","+passwd; } return temp.getBytes(); } }
控制(control)
UIController.java
package com.token.util; import java.io.IOException; import javax.microedition.lcdui.*; import com.token.midlet.MainMidlet; import com.token.model.*; import com.token.view.*; //import com.token.view.components.Color; public class UIController { private MainMidlet midlet; private TokenDataRecord tokenRecord; private WelcomeScreen welcomeScreen; private UserRegist reg; private ActiveScreen activeScreen; private MainScreen mainScreen; private GenPasswd gen; private CheckScreen check; private ViewToken viewToken; private UserManage manage; private ShowHelp help; private UserAuth auth; private PopUpTextBox textBox; int id = 1; public UIController(MainMidlet midlet) { this.midlet = midlet; tokenRecord = new TokenDataRecord(); } public void init() throws IOException{ try { SplashScreen splashScreen = new SplashScreen(); setCurrent(splashScreen); Thread.sleep(1000); Configure.configureColor(); initObject(); //tokenRecord.db_deleteAllRecord(); if(tokenRecord.db_getRecord(1)==null) { //System.out.println("add"); ChaosMethods method = new ChaosMethods(); TokenDataItem tokenItem = new TokenDataItem(1,(method.ChaosInitCode()+",false").getBytes()); id=tokenRecord.db_addRecord(tokenItem); } //System.out.println(id); TokenDataItem tokenItem1 = tokenRecord.db_getRecord(id); //System.out.println(tokenItem1.token+","+tokenItem1.isActive); if(tokenItem1.getStatus().equals("false")) { this.handleEvent(UIController.EventID.EVENT_NEXT_WELCOME_SCREEN,null); }else { String flag = "0"; Object [] args = {flag,""}; this.handleEvent(UIController.EventID.EVENT_MAIN_SCREEN,args); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void initObject() { welcomeScreen = new WelcomeScreen(this); reg= new UserRegist(this); activeScreen = new ActiveScreen(this); ... textBox = new PopUpTextBox(this,"輸入文本","", 1000, TextField.ANY); } //getMethod public void setCurrent(Displayable disp){ midlet.setCurrent(disp); } public void setCurrent(Alert alert, Displayable disp){ midlet.setCurrent(alert, disp); } //定義事件ID內部類 public static class EventID{ private EventID(){ } public static final byte EVENT_EXIT = 0;//退出 public static final byte EVENT_NEXT_WELCOME_SCREEN = 1;//歡迎界面 public static final byte EVENT_NEXT_USER_REGIST_SCREEN = 2;//用戶注冊 public static final byte EVENT_USER_REGIST_EDIT = 3;//用戶注冊編輯 public static final byte EVENT_USER_REGIST_EDIT_BACK = 4;//用戶注冊編輯返回 public static final byte EVENT_NEXT_ACTIVE_SCREEN = 5; //... } //事件處理 public void handleEvent( int eventID, Object[] args) { switch (eventID) { case EventID.EVENT_EXIT: { midlet.exit(false); break; } case EventID.EVENT_NEXT_WELCOME_SCREEN: { welcomeScreen.show(); midlet.setCurrent(welcomeScreen); break; } case EventID.EVENT_NEXT_USER_REGIST_SCREEN: case EventID.EVENT_USER_REGIST_EDIT_BACK: { reg.show(args); Thread thread = new Thread(reg); thread.start(); midlet.setCurrent(reg); break; } case EventID.EVENT_USER_REGIST_EDIT: { textBox.init(args); midlet.setCurrent(textBox); break; } case EventID.EVENT_NEXT_ACTIVE_SCREEN: { activeScreen.show(args); Thread thread = new Thread(activeScreen); thread.start(); midlet.setCurrent(activeScreen); break; } //... default: break; } } }
UserDataRecord.java
package com.token.util; import java.util.Vector; import javax.microedition.rms.RecordComparator; import javax.microedition.rms.RecordEnumeration; import javax.microedition.rms.RecordStore; import javax.microedition.rms.RecordStoreException; import com.token.model.*; public class UserDataRecord { private static final String RECORDSTORE_NAME="USER_DB"; private static RecordStore info; public UserDataRecord(){ } //打開RecordStore,沒有則創建 public void openDataBase() { try { info = RecordStore.openRecordStore(RECORDSTORE_NAME, true); }catch (RecordStoreException ex) { info =null; } } //關閉RecordStore public void closeDataBase() { if (info!= null) { try { info.closeRecordStore(); info=null; } catch (RecordStoreException ex) {} } } //增加記錄 public int db_addRecord(UserDataItem item) { try { this.openDataBase(); byte[] data=item.getBytes(); int id=info.getNextRecordID(); info.addRecord(data,0,data.length); this.closeDataBase(); return id; } catch (RecordStoreException ex) { } return -1; } //更新記錄 public void db_updateRecord(UserDataItem item){ try { this.openDataBase(); byte[] data=item.getBytes(); info.setRecord(item.getId(),data,0,data.length); this.closeDataBase(); } catch (RecordStoreException ex) { } } //訪問一條記錄 public UserDataItem db_getRecord(int id){ UserDataItem item=null; try { this.openDataBase(); item = new UserDataItem(id,info.getRecord(id)); this.closeDataBase(); } catch (RecordStoreException ex) { } return item; } //刪除一條記錄 public void db_deleteRecord(int id){ try { this.openDataBase(); info.deleteRecord(id); this.closeDataBase(); } catch (RecordStoreException ex) {} } //刪除所有記錄 public void db_deleteAllRecord(){ try { RecordStore.deleteRecordStore(RECORDSTORE_NAME); } catch (RecordStoreException ex) {} } //訪問所有記錄 public Vector db_getRecords(){ Vector items=new Vector(10,3); this.openDataBase();//打開RecordStore RecordEnumeration enum1=null; int ind=0; try{ UserDataItem item=null; enum1=info.enumerateRecords(null,new InnerComparator(),false); while(enum1.hasPreviousElement()){ ind=enum1.previousRecordId(); item=new UserDataItem(ind,info.getRecord(ind)); items.addElement(item); } }catch(Exception ex){ex.printStackTrace();} finally{ try{ enum1.destroy(); }catch(Exception e){} this.closeDataBase();//關閉RecordStore }//end finally return items; } //一個簡單的比較器 private class InnerComparator implements RecordComparator{ public int compare(byte[] rec1, byte[] rec2){ if(rec1.length>rec2.length) return FOLLOWS; else if(rec1.length<rec2.length) return PRECEDES; else return EQUIVALENT; } } }
視圖(view)
WelcomeScreen.java
package com.token.view; import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.GameCanvas; import com.token.util.UIController; import com.token.util.StringDealMethod; import com.token.view.components.*; public class WelcomeScreen extends GameCanvas { private UIController controller; private Graphics graphics; private Font ft; private String info; private String info_wrap[]; private int width; private int height; private Menu menu; private Head head; private BackGroud backGroud; public WelcomeScreen(UIController control) { // TODO Auto-generated constructor stub super(false); controller=control; setFullScreenMode(true); graphics = getGraphics(); width = getWidth(); height = getHeight(); menu = new Menu(this); head = new Head(this); backGroud = new BackGroud(this); } public void show() { // TODO Auto-generated method stub //clearScreen(); backGroud.drawBackGroud(this, graphics); head.drawHead(this,graphics,""); menu.drawMenu(this, graphics,"下一步","退出"); drawBody(); } public void drawBody() { ft = Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_BOLD,Font.SIZE_LARGE); info = "歡迎使用!\n" +"1 MVC測試;\n" +"2 自動換行測試,繪制可自動識別換行的字符串。\n"; info_wrap = StringDealMethod.format(info, width-10, ft); graphics.setColor(Color.text); graphics.setFont(ft); for(int i=0; i<info_wrap.length; i++) { graphics.drawString(info_wrap[i], 5, i * ft.getHeight()+40, Graphics.TOP|Graphics.LEFT); } } public void clearScreen() { graphics.setColor(0xff,0xff,0xff); graphics.fillRect(0, 0, width, height); } protected void keyPressed(int keycode) { switch(keycode) { case KeyID.SOFT_RIGHT: { controller.handleEvent(UIController.EventID.EVENT_EXIT,null); break; } case KeyID.SOFT_LEFT: { String editor = "regist_name"; Object [] args = {"registScreen",editor, null,null,null}; controller.handleEvent(UIController.EventID.EVENT_NEXT_USER_REGIST_SCREEN,args); break; } default:; } } }
UserRegist.java
package com.token.view; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.game.GameCanvas; import com.token.model.*; import com.token.util.*; import com.token.view.components.*; public class UserRegist extends GameCanvas implements Runnable { private UIController controller; private Graphics graphics; private Font ft; private Menu menu; private Head head; private BackGroud backGroud; private UserDataRecord userRecord; private String title; private TextEdit textEdit_name; private TextEdit textEdit_passwd; private TextEdit textEdit_passwd_re; private int textEdit_name_x; private int textEdit_name_y; private int textEdit_passwd_x; private int textEdit_passwd_y; private int textEdit_passwd_re_x; private int textEdit_passwd_re_y; private int currentlySelectedIndex = 0; private String username; private String passwd; private String passwd_re; long caretBlinkDelay = 500L; long lastCaretBlink = 0; private String object_name; private String editor; private boolean cursorBlinkOn1; private boolean cursorBlinkOn2; private boolean cursorBlinkOn3; private int width; private int height; public UserRegist(UIController control) { super(false); this.controller=control; this.title = "用戶注冊"; setFullScreenMode(true); graphics = getGraphics(); width = getWidth(); height = getHeight(); menu = new Menu(this); head = new Head(this); backGroud = new BackGroud(this); userRecord = new UserDataRecord(); textEdit_name = new TextEdit(this); textEdit_passwd = new TextEdit(this); textEdit_passwd_re = new TextEdit(this); } public void show(Object[] args) { // TODO Auto-generated method stub setFullScreenMode(true); object_name = ((String)args[0]!=null)?(String)args[0]:""; editor = ((String)args[1]!=null)?(String)args[1]:""; username = ((String)args[2]!=null)?(String)args[2]:""; passwd = ((String)args[3]!=null)?(String)args[3]:""; passwd_re = ((String)args[4]!=null)?(String)args[4]:""; if(editor.equals("regist_name")) { cursorBlinkOn1 = true; cursorBlinkOn2 = false; cursorBlinkOn3 = false; currentlySelectedIndex =0; } else if(editor.equals("regist_passwd")) { cursorBlinkOn1 = false; cursorBlinkOn2 = true; cursorBlinkOn3 = false; currentlySelectedIndex =1; } else if(editor.equals("regist_passwd_re")) { cursorBlinkOn1 = false; cursorBlinkOn2 = false; cursorBlinkOn3 = true; currentlySelectedIndex =2; } //System.out.println(object_name); //System.out.println(editor); draw(); redraw(); } public void draw() { //clearScreen(); backGroud.drawBackGroud(this, graphics); head.drawHead(this,graphics,this.title); menu.drawMenu(this,graphics,"下一步","退出"); drawBody(); } private void redraw() { switch(currentlySelectedIndex) { case 0: { cursorBlinkOn2 = false; cursorBlinkOn3 = false; editor = "regist_name"; break; } case 1: { cursorBlinkOn1 = false; cursorBlinkOn3 = false; editor = "regist_passwd"; break; } case 2: { cursorBlinkOn1 = false; cursorBlinkOn2 = false; editor = "regist_passwd_re"; break; } default:; } textEdit_name.drawTextBox(this, graphics, username, textEdit_name_x, textEdit_name_y, cursorBlinkOn1); textEdit_passwd.drawTextBox(this, graphics, passwd, textEdit_passwd_x, textEdit_passwd_y, cursorBlinkOn2); textEdit_passwd.drawTextBox(this, graphics, passwd_re, textEdit_passwd_re_x, textEdit_passwd_re_y, cursorBlinkOn3); textEdit_name.flushGraphics(); } public void drawBody() { int margin =5; ft = Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_BOLD,Font.SIZE_LARGE); String info = "用戶名:\n"; String info_wrap1[] = StringDealMethod.format(info, width-10, ft); graphics.setFont(ft); graphics.setColor(Color.text); for(int i=0; i<info_wrap1.length; i++) { graphics.drawString(info_wrap1[i],5, (i) * ft.getHeight()+40, Graphics.TOP|Graphics.LEFT); } textEdit_name_x = 5; textEdit_name_y = info_wrap1.length * ft.getHeight()+40; textEdit_name.drawTextBox(this, graphics, username, textEdit_name_x, textEdit_name_y, cursorBlinkOn1); info = "用戶密碼:\n"; String info_wrap2[] = StringDealMethod.format(info, width-10, ft); graphics.setFont(ft); graphics.setColor(Color.text); for(int i=0; i<info_wrap2.length; i++) { graphics.drawString(info_wrap2[i],5, (i+info_wrap1.length) * ft.getHeight()+textEdit_name.height+margin+40, Graphics.TOP|Graphics.LEFT); } textEdit_passwd_x = 5; textEdit_passwd_y = (info_wrap1.length+info_wrap2.length) * ft.getHeight()+textEdit_name.height+margin+40; textEdit_passwd.drawTextBox(this, graphics, passwd, textEdit_passwd_x, textEdit_passwd_y, cursorBlinkOn2); info = "密碼確認:\n"; String info_wrap3[] = StringDealMethod.format(info, width-10, ft); graphics.setFont(ft); graphics.setColor(Color.text); for(int i=0; i<info_wrap3.length; i++) { graphics.drawString(info_wrap3[i],5, (i+info_wrap1.length+info_wrap2.length) * ft.getHeight()+textEdit_name.height+textEdit_passwd.height+2*margin+40, Graphics.TOP|Graphics.LEFT); } textEdit_passwd_re_x = 5; textEdit_passwd_re_y = (info_wrap1.length+info_wrap2.length+info_wrap3.length) * ft.getHeight()+textEdit_name.height+textEdit_passwd.height+2*margin+40; textEdit_passwd_re.drawTextBox(this, graphics, passwd_re, textEdit_passwd_re_x, textEdit_passwd_re_y, cursorBlinkOn3); } public void clearScreen() { graphics.setColor(0xff,0xff,0xff); graphics.fillRect(0, 0, width, height); } public void checkTimeStamp() { long currentTime = System.currentTimeMillis(); //System.out.println("1"); if(lastCaretBlink + caretBlinkDelay < currentTime) { //System.out.println("2"); if(editor.equals("regist_name")) { cursorBlinkOn1 =! cursorBlinkOn1; cursorBlinkOn2 = false; cursorBlinkOn3 = false; } else if(editor.equals("regist_passwd")) { cursorBlinkOn1 = false; cursorBlinkOn2 =! cursorBlinkOn2; cursorBlinkOn3 = false; } else if(editor.equals("regist_passwd_re")) { cursorBlinkOn1 = false; cursorBlinkOn2 = false; cursorBlinkOn3 =! cursorBlinkOn3; } lastCaretBlink = currentTime; } } public void run() { //System.out.println("run"); while(true) { checkTimeStamp(); redraw(); try { synchronized(this) { //System.out.println("3"); wait(50L); } } catch(Exception e) { e.printStackTrace(); } } } protected void keyPressed(int keyCode) { switch(keyCode) { case KeyID.SOFT_RIGHT: { controller.handleEvent(UIController.EventID.EVENT_EXIT,null); break; } case KeyID.SOFT_LEFT: { if(username!="" && passwd!=""&&passwd_re!="") { if(passwd.equals(passwd_re)) { userRecord.db_deleteAllRecord(); if(userRecord.db_getRecord(1)==null) { UserDataItem userItem = new UserDataItem(1,(username+","+passwd).getBytes()); userRecord.db_addRecord(userItem); userItem = null; System.gc(); } String update = "start"; Object [] args = {"activeScreen", null, update}; controller.handleEvent(UIController.EventID.EVENT_NEXT_ACTIVE_SCREEN,args); } } break; } case KeyID.KEY_EDIT: case KEY_NUM0: case KEY_NUM1: case KEY_NUM2: case KEY_NUM3: case KEY_NUM4: case KEY_NUM5: case KEY_NUM6: case KEY_NUM7: case KEY_NUM8: case KEY_NUM9: { //System.out.println(editor); Object[] args = {object_name,editor,username,passwd,passwd_re}; controller.handleEvent(UIController.EventID.EVENT_USER_REGIST_EDIT,args); break; } default:; } keyCode = getGameAction(keyCode); switch(keyCode) { case UP: case LEFT: { currentlySelectedIndex--; if(currentlySelectedIndex<0) { currentlySelectedIndex=0; } else { redraw(); } break; } case DOWN: case RIGHT: { currentlySelectedIndex++; if(currentlySelectedIndex>2) { currentlySelectedIndex=2; } else { redraw(); } break; } } } }
*TextEdit是利用GameCanvas繪制的自定義文本編輯框。后續文章將給出具體實現。
【分析】
1 在MainMidlet調用控制器UIController,并向UIController傳遞midlet作為參數。
controller=new UIController(<span style="color:#ff0000;">this</span>); try { controller.init(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }//
2 控制器的實現是通過一個事件的機制實現的, 在UIController中,先建立一個事件ID的內部類。
public static class EventID{ private EventID(){ } public static final byte EVENT_EXIT = 0;//退出 public static final byte EVENT_NEXT_WELCOME_SCREEN = 1;//歡迎界面 public static final byte EVENT_NEXT_USER_REGIST_SCREEN = 2;//用戶注冊 public static final byte EVENT_USER_REGIST_EDIT = 3;//用戶注冊編輯 public static final byte EVENT_USER_REGIST_EDIT_BACK = 4;//用戶注冊編輯返回 public static final byte EVENT_NEXT_ACTIVE_SCREEN = 5; //... }
3 一次性初始化所有界面,分配內存,調用時,只是執行視圖類的show方法。為什么不將初始話放在調用時進行呢?主要是因為視圖類有多次重用,如果每一次調用都new(初始化,分配內存)一次,手機有限的內存很快會被用光,這是會出現一些程序自動退出的問題。
private void initObject() { welcomeScreen = new WelcomeScreen(this); reg= new UserRegist(this); activeScreen = new ActiveScreen(this); ... textBox = new PopUpTextBox(this,"輸入文本","", 1000, TextField.ANY); }
4 控制器對視圖的處理采用狀態機實現
public void handleEvent( int eventID, Object[] args) { switch (eventID) { case EventID.EVENT_EXIT: { midlet.exit(false); break; } case EventID.EVENT_NEXT_WELCOME_SCREEN: { welcomeScreen.show(); midlet.setCurrent(welcomeScreen); break; } case EventID.EVENT_NEXT_USER_REGIST_SCREEN: case EventID.EVENT_USER_REGIST_EDIT_BACK: { reg.show(args); Thread thread = new Thread(reg); thread.start(); midlet.setCurrent(reg); break; } case EventID.EVENT_USER_REGIST_EDIT: { textBox.init(args); midlet.setCurrent(textBox); break; } case EventID.EVENT_NEXT_ACTIVE_SCREEN: { activeScreen.show(args); Thread thread = new Thread(activeScreen); thread.start(); midlet.setCurrent(activeScreen); break; } //... default: break; } }
5 視圖類初始化時,需要將控制器作為參數初始化,以對事件做出判斷。如WelcomeScreen.java中先做出如下聲明:
private UIController controller;
再在構造函數中,傳遞控制器
public WelcomeScreen(UIController control) { // TODO Auto-generated constructor stub super(false); controller=control;
6 視圖切換事件響應采用如下方式,在keyPressed中,對按鍵事件進行判斷,然后調用UIController的handEvent方法。
protected void keyPressed(int keycode) { switch(keycode) { case KeyID.SOFT_RIGHT: { controller.handleEvent(UIController.EventID.EVENT_EXIT,null); break; } case KeyID.SOFT_LEFT: { String editor = "regist_name"; Object [] args = {"registScreen",editor, null,null,null}; controller.handleEvent(UIController.EventID.EVENT_NEXT_USER_REGIST_SCREEN,args); break; } default:; } } }
7 控制器可以通過handEvent的args傳遞參數,如
String update = "start"; Object [] args = {"activeScreen", null, update}; controller.handleEvent(UIController.EventID.EVENT_NEXT_ACTIVE_SCREEN,args);
UserRegist傳遞了一個update變量給下一個視圖。
8 在看一下模型,在UserDataItem中存儲的是用戶注冊的信息。利用UserDataRecord類對記錄進行操作。
在視圖類中,通過以下方式調用:
先聲明
private UserDataRecord userRecord;
構建對象
userRecord = new UserDataRecord();
使用對象
userRecord.db_deleteAllRecord(); if(userRecord.db_getRecord(1)==null) { UserDataItem userItem = new UserDataItem(1,(username+","+passwd).getBytes()); userRecord.db_addRecord(userItem); userItem = null; System.gc(); }
9 包com.token.view.components是對視圖類中使用的自定義控件的封裝
綜述,這樣就實現了模型、視圖、控制的分離。
上述就是小編為大家分享的JavaMe開發中什么是MVC設計模式了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。