首页 文章 精选 留言 我的

精选列表

搜索[代理式开发],共10000篇文章
优秀的个人博客,低调大师

【移动开发】Android中异步加载数据(二)AsyncTask异步更新界面

今天介绍第二种异步更新界面的方式:AsyncTask 官方文档: AsyncTask enables proper and easyuse of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers. AsyncTask能够更恰当和更简单的去使用UI线程。这个类允许执行后台操作和展现结果在UI线程上,无需操纵线程和/或处理程序。AsyncTask的内部实现是一个线程池,每个后台任务会提交到线程池中的线程执行,然后使用Thread+Handler的方式调用回调函数。 1.AsyncTask抽象出后台线程运行的五个状态: 分别是:1、准备运行,2、正在后台运行,3、进度更新,4、完成后台任务,5、取消任务,对于这五个阶段,AsyncTask提供了五个回调函数: 1、准备运行:onPreExecute(),该回调函数在任务被执行之后立即由UI线程调用。这个步骤通常用来建立任务,在用户接口(UI)上显示进度条。 2、正在后台运行:doInParams...),该回调函数由后台线程在onPreExecute()方法执行结束后立即调用。通常在这里执行耗时的后台计算。计算的结果必须由该函数返回,并被传递到onPostExecute()中。在该函数内也可以使用publishProgress(Progress...)来发布一个或多个进度单位(unitsof progress)。这些值将会在onProgressUpdate(Progress...)中被发布到UI线程。 3. 进度更新:onProgressUpdate(Progress...),该函数由UI线程在publishProgress(Progress...)方法调用完后被调用。一般用于动态地显示一个进度条。 4. 完成后台任务:onPostExecute(Result),当后台计算结束后调用。后台计算的结果会被作为参数传递给这一函数。 5、取消任务:onCancelled (),在调用AsyncTask的cancel()方法时调用 2.使用: AsyncTask必须使用子类。子类会覆盖至少一个方法(doInParams…)),通常将覆盖第二个(onPostExecute(结果)。< /span> AsyncTask的构造函数有三个模板参数:AsyncTask<Params, Progress, Result> 1.Params,传递给后台任务的参数类型。 2.Progress,后台计算执行过程中,进步单位(progress units)的类型。(就是后台程序已经执行了百分之几了。) 3.Result, 后台执行返回的结果的类型。 AsyncTask并不总是需要使用上面的全部3种类型。标识不使用的类型很简单,只需要使用Void类型即可。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.Toast; /** * AsyncTask 实现异步加载图片 * @author ZHF * */ public class MainActivity extends Activity { public static final String IMG_URL= "http://images.51cto.com/images/index/Images/Logo.gif" ; Button btn_asynctask; ImageView imgView; ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); //加载控件 imgView = (ImageView) this .findViewById(R.id.imageView); btn_asynctask = (Button) this .findViewById(R.id.btn_AsyncTask); progressBar = (ProgressBar) this .findViewById(R.id.progressBar); //绑定监听器 btn_asynctask.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { GetImgTask getImgTask = new GetImgTask(); getImgTask.execute(IMG_URL); //执行该任务 } }); } /**获取网络图片任务**/ private class GetImgTask extends AsyncTask<String, Integer, Bitmap> { /**在 doInParams...)之前被调用,在ui线程执行 **/ @Override protected void onPreExecute() { imgView.setImageBitmap( null ); progressBar.setProgress( 0 ); //进度条复位 } /**在后台线程中执行的任务**/ @Override protected Bitmap doInString... params) { publishProgress( 0 ); //会调用onProgressUpdate更新界面 InputStream inputStream = null ; Bitmap imgBitmap = null ; try { URL url = new URL(IMG_URL); if (url != null ) { HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout( 2000 ); connection.setDoInput( true ); connection.setRequestMethod( "GET" ); int code = connection.getResponseCode(); if ( 200 == code) { inputStream = connection.getInputStream(); imgBitmap = BitmapFactory.decodeStream(inputStream); } } } catch (Exception e) { e.printStackTrace(); return null ; } publishProgress( 100 ); //下载完成,更新进度条为满格 //这里不是UI线程,故不能直接setImage(imgBitmap), return imgBitmap; } /**在调用publishProgress之后被调用,在ui线程执行 **/ @Override protected void onProgressUpdate(Integer... values) { progressBar.setProgress(values[ 0 ]); //设置进度条的进度 } /**在后台线程执行完成之后,调用该方法,获取数据更新界面**/ @Override protected void onPostExecute(Bitmap result) { if (result != null ) { Toast.makeText(MainActivity. this , "成功获取图片" , Toast.LENGTH_LONG).show(); imgView.setImageBitmap(result); } else { Toast.makeText(MainActivity. this , "获取图片失败" , Toast.LENGTH_LONG).show(); } } /**取消任务,在ui线程执行 **/ @Override protected void onCancelled() { progressBar.setProgress( 0 ); //进度条复位 super .onCancelled(); } } } 分析: 1.点击按钮之后,创建一个任务,参数值为url(所以第一个参数为String) 2.UI线程执行onPreExecute(),把ImageView的图片清空,progrssbar的进度清零。 3.后台线程执行doInBackground(),不可以在doInBackground()操作ui,调用publishProgress(0)更新进度,此时会调用onProgressUpdate(Integer...progress)更新进度条(进度用整形表示,因此AsyncTask的第二个模板参数是Integer)。函数最后返回result(例子中是返回Bitmap类型,因此AsyncTask的第三个模板参数是Bitmap)。 4.当后台任务执行完成后,调用onPostExecute(Result),传入的参数是doInBackground()中返回的对象。 参考博客:http://blog.csdn.net/mylzc/article/details/6772129 源码下载请看附件 附件:http://down.51cto.com/data/2363166 本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1252156,如需转载请自行联系原作者

优秀的个人博客,低调大师

【移动开发】Android中一些你可能不太知道的东西

今天,我们来浅谈一下你可能不知道的一些东东 1.不用在意剩余内存的大小 其实很多人都是把使用其他系统的习惯带过来来了。android大多应用没有退出的设计其实是有道理的(下一篇我会讲到Android应用程序完全退出方法),这和系统对进程的调度机制有关系。如果你知道java,就能更清楚这机制了。其实和java的垃圾回收机制类似,系统有一个规则来回收内存。进行内存调度 有个阀值,只有低于这个值系统才会按一个列表来关闭用户不需要的东西。当然这个值默认设置得很小,所以你会看到内存老在很少的数值徘徊。但事实上他并不影响速度。相反加快了下次启动应用的速度。 这本来是android标榜的优势之一,如果人为去关闭进程,没有太大必要。特别是使用自动关进程的软件。(这里解决了大家非要关进程的误区!) 2.为什么内存少的时候运行大型程序会慢呢? 那其实很简单,在内存剩余不多时打开大型程序,会触发系统自身的调进程调度策略,这是十分消耗系统资源的操作,特别是在一个程序频繁向系统申请内存的时候。这种情况下系统并不会关闭所有打开的进程,而是选择性关闭,频繁的调度自然会拖慢系统。所以,通过更改内存阀值的程序可以有一定改善。但改动也可能带来一些问题,取决于值的设定。 那么,进程管理软件有无必要呢?有的。就是在运行大型程序之前,你可以手动关闭一些进程释放内存,可以显著的提高运行速度。但一些小程序,完全可交由系统自己管理。 3.不关程序是不是会更耗电? 这里讲解一下android后台的原理,你就明白了。android的应用在被切换到后台时,它其实已经被暂停了,并不会消耗cpu资源,只保留了运行状态。所以为什么有的程序切出去重进会到主界面。但是,一个程序如果想要在后台处理些东西,如音乐播放,它就会开启一个服务。服务可在后台持续运行,所以在后台耗电的也只有带服务的应用了。这个在进程管理软件里能看到,标签是service。 所以没有带服务的应用在后台是完全不耗电的,没有必要关闭。这种设计本来就是一个非常好的设计,下次启动程序时,会更快,因为不需要读取界面资源,何必要关掉他们抹杀这个android的优点呢? 4.为什么android一个应用看起来那么耗内存 大家知道,android上的应用是java,当然需要虚拟机,而android上的应用是带有独立虚拟机的,也就是每开一个应用就会打开一个独立的虚拟机。这样设计的原因是可以避免虚拟机崩溃导致整个系统崩溃,但代价就是需要更多内存。(跟塞班也不一样,安卓不容易死机重启) 以上这些设计确保了android的稳定性,正常情况下最多单个程序崩溃,但整个系统不会崩溃,也永远没有内存不足的提示出现。 大家可能是被windows毒害得太深了,总想保留更多的内存,但实际上这并不一定会提升速度,相反却丧失了程序启动快的这一系统特色,很没必要。大家不妨按我说的习惯来用用这个系统。 本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1248169 ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android UI开发第十五篇——分享一个登录缓冲界面

今天在网上发现了一个很漂亮的缓冲界面,在这里分享一下。主要还是用的android Anim。 publicclassMainextendsActivity{ privateAnimationanm; privateintmarginsTop; publicList<ImageView>images; publicLinearLayoutll; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); DisplayMetricsdm=this.getResources().getDisplayMetrics(); intheight=dm.heightPixels; marginsTop=height-100; anm=AnimationUtils.loadAnimation(this,R.anim.myanim); ll=newLinearLayout(this); ll.setBackgroundResource(R.drawable.background); images=newArrayList<ImageView>(); initImage(ll); playAnimation(); setContentView(ll); } privatevoidplayAnimation(){ newThread(){ @Override publicvoidrun() { try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } intruncount=0; while(true) { if(runcount<2) { for(inti=0;i<=6;i++) { handler.sendEmptyMessage(i); try{ Thread.sleep(400); }catch(InterruptedExceptione){ e.printStackTrace(); } } runcount++; }else { handler.sendEmptyMessage(99); runcount=0; } } } }.start(); } Handlerhandler=newHandler(){ @Override publicvoidhandleMessage(Messagemsg){ switch(msg.what) { case0: images.get(0).setImageDrawable(Main.this.getResources().getDrawable(R.drawable.l)); images.get(0).startAnimation(anm); break; case1: images.get(1).setImageDrawable(Main.this.getResources().getDrawable(R.drawable.o)); images.get(1).startAnimation(anm); break; case2: images.get(2).setImageDrawable(Main.this.getResources().getDrawable(R.drawable.a)); images.get(2).startAnimation(anm); break; case3: images.get(3).setImageDrawable(Main.this.getResources().getDrawable(R.drawable.d)); images.get(3).startAnimation(anm); break; case4: images.get(4).setImageDrawable(Main.this.getResources().getDrawable(R.drawable.i)); images.get(4).startAnimation(anm); break; case5: images.get(5).setImageDrawable(Main.this.getResources().getDrawable(R.drawable.n)); images.get(5).setAnimation(anm); break; case6: images.get(6).setImageDrawable(Main.this.getResources().getDrawable(R.drawable.g)); images.get(6).setAnimation(anm); break; case99: clearImage(); break; } } }; privatevoidclearImage() { for(ImageViewimage:images) { image.setImageDrawable(null); image.destroyDrawingCache(); } } privatevoidinitImage(LinearLayoutlayout){ layout.setGravity(Gravity.CENTER_HORIZONTAL); LinearLayout.LayoutParamsparam=newLinearLayout.LayoutParams(40,40); param.setMargins(30,marginsTop,0,0); LinearLayout.LayoutParamsparam2=newLinearLayout.LayoutParams(40,40); param2.setMargins(-5,marginsTop,0,0); ImageViewl=newImageView(this); l.setLayoutParams(param); layout.addView(l); images.add(l); ImageViewo=newImageView(this); o.setLayoutParams(param2); layout.addView(o); images.add(o); ImageViewa=newImageView(this); a.setLayoutParams(param2); layout.addView(a); images.add(a); ImageViewd=newImageView(this); d.setLayoutParams(param2); layout.addView(d); images.add(d); ImageViewi=newImageView(this); i.setLayoutParams(param2); layout.addView(i); images.add(i); ImageViewn=newImageView(this); n.setLayoutParams(param2); layout.addView(n); images.add(n); ImageViewg=newImageView(this); g.setLayoutParams(param2); layout.addView(g); images.add(g); } } <?xmlversion="1.0"encoding="utf-8"?> <setxmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scaleandroid:interpolator="@android:anim/accelerate_interpolator" android:fromXScale="0.5" android:toXScale="1.2" android:fromYScale="0.5" android:toYScale="1.2" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:startOffset="-50" android:duration="100" /> </set> 代码地址:http://www.devdiv.com/thread-101608-1-1.html 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/817279,如需转载请自行联系原作者

优秀的个人博客,低调大师

分享几点Android 开发中的小技巧吧。不知道算不算?

也不想多说多,就拿几点来给大家分享吧: Android 在XML里面共享同一布局文件 使用XML的方式为背景添加渐变的效果 如何用代码自定义Android 自动生成的标题? 在ActivityGroup里面如何访问子Activity的View 并操作它去改变UI? 就上面四点吧,这些好像在搜索里面不大搜索得到,我今天就拿出来讲讲,好像己经有几个星期没有更新过博客的Android 文章了,呵呵,之前承诺的Ebook 源码也没有跟上,最近人懒,刚买的Ipad 一直在玩,荒废了学业呢。。。。。 好吧。废话不多说了,一个个说吧。 1.Android 在XMl里面共享同一布局文件 一直以为共享同一布局文件都是在之前写好的布局之后复制过来,或者通过 java代码使用layoutInflater Add进来的。但今天提供了一个更为方便的使用方法,可以在你的任意LAYOUT文件里面将其他的LAYOUT文件拿过来使用,代码也很简单,如下: <? xmlversion="1.0"encoding="UTF-8" ?> < LinearLayout android:id ="@+id/FrameLayout01" android:background ="@drawable/layout_background" android:layout_width ="fill_parent" android:layout_height ="wrap_content" xmlns:android ="http://schemas.android.com/apk/res/android" > < TextView android:text ="欢迎你使用本软件" android:id ="@+id/TextView01" android:textColor ="#f0f0f0" android:layout_width ="wrap_content" android:layout_height ="wrap_content" ></ TextView > </ LinearLayout > 这是我定义的公用layout 文件,我给他起名为:title 然后我们在另外的布局文件如下使用: < include layout ="@layout/title" /> 即可将title 的布局直接拿到我们当前的布局文件中。 Tip:使用include标记将layout 放入我们当前的layout文件,也可以直接使用当前view .findViewByid得到title 布局文件中的任意View 。 2.使用XML的方式为背景添加渐变的效果 为背景实现渐变效果,最传统的方法是用PS制作一张渐变的效果图,但我人懒 没去学PS技术,也懒得更增加一个图片在应用里面,这里使用了Google 提供的一个非常棒的方法来解决背景渐变的功能。 首先,在Drawable 文件夹里面添加一个xml文件,然后写入如下代码: <? xmlversion="1.0"encoding="UTF-8" ?> < shape xmlns:android ="http://schemas.android.com/apk/res/android" > < gradient android:startColor ="#52adcd" android:endColor ="#1c87b1" android:angle ="270.0" > </ gradient > </ shape > 对应属性比较简单,这里不多做介绍,android:shape="rectangle" 为代表渐变的形状为矩形块。android:angle ="270.0"代表角度为270,由上到下的渐变,如果我改变成0那么就变成了从左到右的渐变,如果改变90.0那么渐变会从下边往下渐变,朋友们可以多改变一下参数试试效果。 发个效果图吧: Tip:效果图用的角度是0。 3.如何用代码自定义Android 自动生成的标题? 这个比较简单只用了三句代码: requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.main); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.title); 效果如下图: Tip:这三句代码的位置必须如上代码。 4.在ActivityGroup里面如何访问子Activity的View 并操作它去改变UI? 要知道如何在ActivityGroup里面操作子Activity的布局View 那么得先了解一下,如何将Activity放入ActivityGroup 里面,这里我封装了一个小小的方法,公供参考: /** *为ActivityGroup的一个ViewGroup设置动态的ActivityView对象 * * @param 上下文 * @param LocalActivityManager对象 * @param ActivityGroup想要包容Activity *View对象的容器(ViewGroup) * @param 通过Intent的意图打算启用哪个Activity类 * @param 开始Activity *设置的Id */ public static void getView(Contextcontext,LocalActivityManagerlam, LinearLayoutlayout_load,Class <?> cls,StringId){ Intentintent = new Intent(context,cls); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); Windoww = lam.startActivity(Id,intent); Viewv = w.getDecorView(); layout_load.removeAllViews(); layout_load.setPadding( 5 , 5 , 5 , 5 ); layout_load.addView(v, new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT)); } 然后在ActivityGroup页面如此使用: private LocalActivityManagermanager; // 声明一个LocalActivityManager对象 manager = getLocalActivityManager(); // 得到这个对象 界面初始化时: /** *初始化 */ void init(){ comonHelp.getView( this ,manager,main,preferenceSet. class , " swc " ); } 有了设置的ID了,那就可以得到当前的Activity 了。 下面给出我用过的一段代码,以作参考: SharedPreferences.Editoreditor = getSharedPreferences( " com.swc.yaomei_preferences " , Activity.MODE_PRIVATE).edit(); LocalActivityManagermanager = getLocalActivityManager(); PreferenceActivityacitivty = (PreferenceActivity)manager .getActivity( " swc " ); for ( int i = 0 ;i < 9 ;i ++ ){ editor.putString( " KEY_ " + i, " N/A " ); PreferenceScreenExtext = (PreferenceScreenExt)acitivty .findPreference( " KEY_ " + i); RelativeLayoutlayout = (RelativeLayout)ext .getLayout(); TextViewsummary = (TextView)layout.getChildAt( 1 ); summary.setText( " N/A " ); } editor.commit(); System.gc(); 上面的PreferenceActivity是得到一个PreferenceAcitity 因为我是要修改位于ActivityGroup里面对应的Preference所以这里要获得一个PreferenceAcitity ,如果你是一个普通的Activity 直接得到一个Activity 对象就行,之后的操作都是一致的。 好了,虽然就这几个小技巧,但还算是比较实用滴。。。 本文转自 terry_龙 51CTO博客,原文链接:http://blog.51cto.com/terryblog/408151,如需转载请自行联系原作者

优秀的个人博客,低调大师

Java微服务开发指南 -- 下一步该了解什么?

下一步该了解什么? 我们在这本小册子里面介绍了非常多的知识,但是它远远不够涵盖一切!我们需要知道,这只是冰山一角,有非常多的微服务所涉及到的领域在本书中没有探讨。在最后这个章节,我们将会简要的介绍一些你必须了解的概念,并将这些联系留给读者进行深入研究。 配置 配置(Configuration)是分布式系统中非常重要的部分,而在微服务架构中变得愈发重要和困难。我们需要在配置和不可变递交(Immutable delivery)之间寻求平衡,因为我们不希望出现服务的碎片化。例如:我们需要能够改变日志级别,在A/B测试上切换特性,配置数据库连接或者使用秘钥或者密码,我们回顾之前介绍的三个Java微服务框架,但是每个框架的配置方式略微不同,那么在非Java环境下的微服务配置方式又会变成什么样子呢? 如果以配置的形式存在,不同的需求就

优秀的个人博客,低调大师

Android UI开发第二十三篇——分享书架UI实现

android中有很多的电子书阅读应用,应用中都仿真了书架的实现,这里也分享一篇读书应用的书架实现: java: public class ShelvesView extends GridView { private Bitmap mShelfBackground; private int mShelfWidth; private int mShelfHeight; private Bitmap mWebLeft; private Bitmap mWebRight; private int mWebRightWidth; public ShelvesView(Context context) { super(context); init(context); } public ShelvesView(Context context, AttributeSet attrs) { super(context, attrs); load(context, attrs, 0); init(context); } public ShelvesView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); load(context, attrs, defStyle); init(context); } private void load(Context context, AttributeSet attrs, int defStyle) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ShelvesView, defStyle, 0); final Resources resources = getResources(); final int background = a.getResourceId(R.styleable.ShelvesView_shelfBackground, 0); final Bitmap shelfBackground = BitmapFactory.decodeResource(resources, background); if (shelfBackground != null) { mShelfWidth = shelfBackground.getWidth(); mShelfHeight = shelfBackground.getHeight(); mShelfBackground = shelfBackground; } mWebLeft = BitmapFactory.decodeResource(resources, R.drawable.web_left); final Bitmap webRight = BitmapFactory.decodeResource(resources, R.drawable.web_right); mWebRightWidth = webRight.getWidth(); mWebRight = webRight; a.recycle(); } private void init(Context context) { StateListDrawable drawable = new StateListDrawable(); SpotlightDrawable start = new SpotlightDrawable(context, this); start.disableOffset(); SpotlightDrawable end = new SpotlightDrawable(context, this, R.drawable.spotlight_blue); end.disableOffset(); TransitionDrawable transition = new TransitionDrawable(start, end); drawable.addState(new int[] { android.R.attr.state_pressed }, transition); final SpotlightDrawable normal = new SpotlightDrawable(context, this); drawable.addState(new int[] { }, normal); normal.setParent(drawable); transition.setParent(drawable); setSelector(drawable); setDrawSelectorOnTop(false); } @Override protected void dispatchDraw(Canvas canvas) { final int count = getChildCount(); final int top = count > 0 ? getChildAt(0).getTop() : 0; final int shelfWidth = mShelfWidth; final int shelfHeight = mShelfHeight; final int width = getWidth(); final int height = getHeight(); final Bitmap background = mShelfBackground; for (int x = 0; x < width; x += shelfWidth) { for (int y = top; y < height; y += shelfHeight) { canvas.drawBitmap(background, x, y, null); } } if (count == 0) { canvas.drawBitmap(mWebLeft, 0.0f, top + 1, null); canvas.drawBitmap(mWebRight, width - mWebRightWidth, top + shelfHeight + 1, null); } super.dispatchDraw(canvas); } @Override public void setPressed(boolean pressed) { super.setPressed(pressed); final Drawable current = getSelector().getCurrent(); if (current instanceof TransitionDrawable) { if (pressed) { ((TransitionDrawable) current).startTransition( ViewConfiguration.getLongPressTimeout()); } else { ((TransitionDrawable) current).resetTransition(); } } } } 代码:http://download.csdn.net/detail/xyz_lmn/4698124 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/1230767,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册