An_MVP模式okhttp_RecyclerView

運用MVP模式寫(okhttp)解析json,數(shù)據(jù)傳輸?shù)絉ecyclerView中;
一、三個層Model,view,Presenter
二、導(dǎo)入okhttp,okio,RecyclerView依賴;
加入網(wǎng)絡(luò)權(quán)限<uses-permission android:name="android.permission.INTERNET"/>
三、封裝Adapter實現(xiàn)效果;

model:接口 IShowRecyclerViewModel

public interface IShowRecyclerViewModel {
    void showData(int type,Callback callback);
}

model:類 ShowRecyclerViewModel

public class ShowRecyclerViewModel implements IShowRecyclerViewModel {

    @Override
    public void showData(int type,Callback callback) {
        OkHttpUtils.getInstance().doGet("http://www.yulin520.com/a2a/impressApi/news/mergeList?sign=C7548DE604BCB8A17592EFB9006F9265&pageSize=20&gender=2&ts=1871746850&page="+type+"",callback);
    }
}

View :接口 IShowRecyclerViewView

public interface ShowRecyclerViewView {
    void showRecyclerView(List<Max.DataBean> list);
    int getID();

}

Presenter: 類 ShowRecyclerViewPresenter
Max.class是bean包下的json類

public class ShowRecyclerViewpresenter {
    IShowRecyclerViewModel model;
    ShowRecyclerViewView view;
    List<Max.DataBean> list;
    Context context;
    public  ShowRecyclerViewpresenter(Context context, ShowRecyclerViewView view){
        this.context=context;
        this.view=view;
        model=new ShowRecyclerViewModel();
    }
   public void showRecyclerView(){
       int type=view.getID();
       model.showData(type, new OnUiCallback() {
           @Override
           public void onFailed(Call call, IOException e) {

           }

           @Override
           public void onSuccess(String result) throws IOException {
               Gson gson=new Gson();
               Max max = gson.fromJson(result, Max.class);
               list=max.getData();
               Toast.makeText(context,list.toString(),Toast.LENGTH_SHORT).show();
               view.showRecyclerView(list);
           }
       });

    }
}

Okhttp的封裝類:
OkHttpUtils類(get請求):

public class OkHttpUtils {
    private Handler handler=new Handler();
    public Handler getHandler(){
        return handler;
    }
    private static OkHttpUtils okHttpUtils=new OkHttpUtils();
    private OkHttpUtils(){};
    public static OkHttpUtils getInstance(){
        return okHttpUtils;
    }
    private OkHttpClient client;
    private void initOkHttpClient(){
        if(client==null){
            client=new OkHttpClient().newBuilder().build();
        }
    }
    public void doGet(String url, Callback callback){
        initOkHttpClient();
        Request request=new Request.Builder().url(url).build();
        Call call=client.newCall(request);
        call.enqueue(callback);
    }
}

Okhttp的封裝類:
OnUiCallback類(get請求):

public abstract class OnUiCallback implements Callback {
    private Handler handler=OkHttpUtils.getInstance().getHandler();
    public abstract void onFailed(Call call,IOException e);
    public abstract void onSuccess(String result)throws IOException;

    @Override
    public void onFailure(final Call call, final IOException e) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                onFailure(call,e);
            }
        });
    }

    @Override
    public void onResponse(Call call, final Response response) throws IOException {
        final String result=response.body().string();
        handler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    onSuccess(result);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

MainActivity:

public class MainActivity extends AppCompatActivity implements ShowRecyclerViewView{

    private RecyclerView mRv;
    int type=1;
    ShowRecyclerViewpresenter presenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        presenter=new ShowRecyclerViewpresenter(this,this);
        presenter.showRecyclerView();

    }
    private void initView() {
        mRv = (RecyclerView) findViewById(R.id.rv);
        LinearLayoutManager layoutManager=new LinearLayoutManager(this);
        mRv.setLayoutManager(layoutManager);
        mRv.addItemDecoration(new DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL));
    }

    @Override
    public void showRecyclerView(List<Max.DataBean> list) {
      MyAdapter myadapter=new MyAdapter(MainActivity.this,list);
        mRv.setAdapter(myadapter);
    }

    @Override
    public int getID() {
        return type;
    }

}

Adapter:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
    Context context;
    List<Max.DataBean> list;
    public MyAdapter (  Context context, List<Max.DataBean> list){
        this.context=context;
        this.list=list;
    }
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view=View.inflate(context,R.layout.items,null);
        MyViewHolder holder=new MyViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        ImageLoader.getInstance().displayImage(list.get(position).getImg(),holder.ivhead);
        holder.tvage.setText(list.get(position).getUserAge()+"歲");
        holder.tvh.setText(list.get(position).getOccupation());
        holder.tvmessage.setText(list.get(position).getIntroduction());
    }

    @Override
    public int getItemCount() {
        return list==null?0:list.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder{
        TextView tvmessage;
        TextView tvage;
        TextView tvh;
        ImageView ivhead;
        public MyViewHolder(View itemView) {
            super(itemView);
            tvage=itemView.findViewById(R.id.tvage);
            tvh=itemView.findViewById(R.id.tvh);
            tvmessage=itemView.findViewById(R.id.tvmessage);
            ivhead=itemView.findViewById(R.id.ivhead);
        }
    }
}

最后我們用ImageLoader來加載網(wǎng)絡(luò)獲取的數(shù)據(jù):
定義MyApp類:
在清單文件中別忘了加上
android:name=".MyApp"

public class MyApp extends Application {
    ImageLoader imageLoader;
    @Override
    public void onCreate() {
        super.onCreate();
        File file = this.getCacheDir();

        DisplayImageOptions options = new DisplayImageOptions.Builder()
                .showImageOnLoading(R.mipmap.ic_launcher) // 加載未完成時顯示的自定義圖片
                .showImageForEmptyUri(R.mipmap.ic_launcher) // 鏈接為空時的占位圖
                .showImageOnFail(R.mipmap.ic_launcher_round) // 加載失敗時顯示自定義圖片
                .resetViewBeforeLoading(false)  // 在加載前是否重置 view ,默認(rèn)為false
                .delayBeforeLoading(1000)  //設(shè)置在開始加載前的延遲時間,單位為毫秒
                .cacheInMemory(true) // 是否啟用內(nèi)存緩存,默認(rèn)為false
                .cacheOnDisk(true) // 是否啟用磁盤緩存,默認(rèn)為false
                .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // 圖片的縮放類型
                .bitmapConfig(Bitmap.Config.ARGB_8888) // 圖片的色彩格式
                .handler(new Handler()) // handler 對象,消息處理
                .build();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                this)
                // max width, max height,即保存的每個緩存文件的最大長寬
                .memoryCacheExtraOptions(480, 800)
                // 線程池內(nèi)加載的數(shù)量
                .threadPoolSize(3)
                // 線程優(yōu)先級
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .defaultDisplayImageOptions(options)
                // You can pass your own memory cache implementation你可以通過自己的內(nèi)存緩存實現(xiàn)
                // .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024))
                // .memoryCacheSize(2 * 1024 * 1024)
                //硬盤緩存50MB
                .diskCacheSize(50 * 1024 * 1024)
                //將保存的時候的URI名稱用MD5
                .diskCacheFileNameGenerator(new Md5FileNameGenerator())
                // 加密
                .diskCacheFileNameGenerator(new HashCodeFileNameGenerator())//將保存的時候的URI名稱用HASHCODE加密
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                .diskCacheFileCount(100) //緩存的File數(shù)量
                .diskCache(new UnlimitedDiscCache(file))// 自定義緩存路徑
                // .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
                // .imageDownloader(new BaseImageDownloader(context, 5 * 1000,
                // 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超時時間
                .writeDebugLogs() // Remove for release app
                .build();

        ImageLoader.getInstance().init(config);
    }

}

下面分享一個RecyclerView多條目加載的AdapterDemo(MVC):
加載一個頭布局

private void initrvData() {
        myadapter=new MyRVAdapter();
        mXrv.setAdapter(myadapter);
        TextView title = new TextView(MainActivity.this);
        myadapter.addHeader(title);

    }


 class MyRVAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
        public static final int TYPE_HEADER = 0;
        public static final int TYPE_BO = 1;
        List<View> list = new ArrayList<>();

        public void addHeader(View view) {
            list.add(view);
        }
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if (viewType == TYPE_HEADER) {
                View view = View.inflate(MainActivity.this, R.layout.xrvhead, null);
                MyHeaderHolder headerHolder = new MyHeaderHolder(view);
                return headerHolder;
            } else {
                View view = View.inflate(MainActivity.this, R.layout.xrvitem, null);
                MyViewHolder holder = new MyViewHolder(view);
                return holder;
            }
        }
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            if (holder instanceof MyHeaderHolder) {
                ((MyHeaderHolder) holder).h_title.setText(m.getBillboard().getName());
                ((MyHeaderHolder) holder).h_name.setText(m.getBillboard().getUpdate_date());
                ((MyHeaderHolder) holder).h_info.setText(m.getBillboard().getComment());
                ImageLoader.getInstance().displayImage(m.getBillboard().getPic_s210(), ((MyHeaderHolder) holder).h_iv);
            }

            if (holder instanceof MyViewHolder) {
                ((MyViewHolder) holder).title.setText(listrv.get(position).getTitle());
                ((MyViewHolder) holder).author.setText(listrv.get(position).getAuthor());
                ((MyViewHolder) holder).name.setText(listrv.get(position).getAlbum_title());
                ImageLoader.getInstance().displayImage(listrv.get(position).getPic_big(), ((MyViewHolder) holder).iv);
            }
        }
        @Override
        public int getItemCount() {
            return listrv == null ? 0 : listrv.size();
        }


        @Override
        public int getItemViewType(int position) {
            if (position < list.size()) {
                return TYPE_HEADER;
            } else {
                return TYPE_BO;
            }
        }

        class MyHeaderHolder extends RecyclerView.ViewHolder {

            TextView h_title, h_name, h_info, h_author;
            ImageView h_iv;
            RelativeLayout rl;

            public MyHeaderHolder(View itemView) {
                super(itemView);
                h_iv = itemView.findViewById(R.id.header_iv);
                h_title = itemView.findViewById(R.id.header_title);
                h_author = itemView.findViewById(R.id.header_author);
                h_name = itemView.findViewById(R.id.header_name);
                h_info = itemView.findViewById(R.id.header_info);
                rl = itemView.findViewById(R.id.rl);
            }
        }

        class MyViewHolder extends RecyclerView.ViewHolder {

            TextView title, name, author;
            ImageView iv;


            public MyViewHolder(View itemView) {
                super(itemView);

                title = itemView.findViewById(R.id.title);
                name = itemView.findViewById(R.id.name);
                iv = itemView.findViewById(R.id.iv);
                author = itemView.findViewById(R.id.author);
            }
        }
    }

定義全局異常捕獲處理器;
演示空指針異常時使用全局異常捕獲處理器提示錯誤信息;
將錯誤日志成功保存到sd卡;
封裝class CrashHandler.class 和CrashApplication.class

package com.example.login_recyclerview20171023;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


public class CrashHandler implements Thread.UncaughtExceptionHandler {
    public  static  final  String TAG="CrashHandler";
    //系統(tǒng)默認(rèn)的UncaughtException處理類
    private Thread.UncaughtExceptionHandler mDefaultHandler;
    //系統(tǒng)默認(rèn)的UncaughtException處理類
    private  static  CrashHandler INSTANCE=new CrashHandler();
    //程序的Context對象
    private Context mContext;
    //用來存儲設(shè)備信息和異常信息
    private Map<String, String> infos = new HashMap<String, String>();

    //用于格式化日期,作為日志文件名的一部分

    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    /** 保證只有一個CrashHandler實例 */
    private CrashHandler() {
    }

    /** 獲取CrashHandler實例 ,單例模式 */
    public static CrashHandler getInstance() {
        return INSTANCE;
    }

    /**
     * 初始化
     *
     * @param context
     */
    public void init(Context context) {
        mContext = context;
        //獲取系統(tǒng)默認(rèn)的UncaughtException處理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        //設(shè)置該CrashHandler為程序的默認(rèn)處理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }
    /**
     * 當(dāng)UncaughtException發(fā)生時會轉(zhuǎn)入該函數(shù)來處理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {

        if (!handleException(ex) && mDefaultHandler != null) {
            //如果用戶沒有處理則讓系統(tǒng)默認(rèn)的異常處理器來處理
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                Log.e(TAG, "error : ", e);
            }
            //退出程序
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        }
    }
    /**
     * 自定義錯誤處理,收集錯誤信息 發(fā)送錯誤報告等操作均在此完成.
     *
     * @param ex
     * @return true:如果處理了該異常信息;否則返回false.
     */
    private boolean handleException(Throwable ex) {
        if (ex == null) {
            return false;
        }
        //使用Toast來顯示異常信息
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(mContext, "很抱歉,程序出現(xiàn)異常,即將退出.", Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }.start();
        //收集設(shè)備參數(shù)信息
        collectDeviceInfo(mContext);
        //保存日志文件
        saveCrashInfo2File(ex);
        return true;
    }



    private void collectDeviceInfo(Context ctx) {


        try {
            PackageManager pm = ctx.getPackageManager();
            PackageInfo pi = null;
            pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
            if (pi != null) {
                String versionName = pi.versionName == null ? "null" : pi.versionName;
                String versionCode = pi.versionCode + "";
                infos.put("versionName", versionName);
                infos.put("versionCode", versionCode);
            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "an error occured when collect package info", e);
        }


        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                infos.put(field.getName(), field.get(null).toString());
                Log.d(TAG, field.getName() + " : " + field.get(null));
            } catch (Exception e) {
                Log.e(TAG, "an error occured when collect crash info", e);
            }
        }
    }

    /**
     * 保存錯誤信息到文件中
     *
     * @param ex
     * @return  返回文件名稱,便于將文件傳送到服務(wù)器
     */
    private String saveCrashInfo2File(Throwable ex) {
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : infos.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            sb.append(key + "=" + value + "\n");
        }

        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        String result = writer.toString();
        sb.append(result);
        try {
            long timestamp = System.currentTimeMillis();
            String time = formatter.format(new Date());
            String fileName = "crash-" + time + "-" + timestamp + ".log";
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                String path = "/sdcard/crash/";
                File dir = new File(path);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(path + fileName);
                fos.write(sb.toString().getBytes());
                fos.close();
            }
            return fileName;
        } catch (Exception e) {
            Log.e(TAG, "an error occured while writing file...", e);
        }
        return null;
    }

    /**
     * 網(wǎng)絡(luò)是否可用
     *
     * @param context
     * @return
     */
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo[] info = mgr.getAllNetworkInfo();
        if (info != null) {
            for (int i = 0; i < info.length; i++) {
                if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }
            }
        }
        return false;
    }
}

public class CrashApplication extends Application {
    private static Context mContext;

    @Override
    public void onCreate() {
        super.onCreate();
        this.mContext = this;
        CrashHandler.getInstance().init(this);
    }

}

清單文件里配置name******
下面補(bǔ)充一個Xrecyclerview的 實例:
添加依賴:compile 'com.jcodecraeer:xrecyclerview:1.3.2'
與recyclerview類似 不同的是可以實現(xiàn)下拉加載和上拉刷新功能:
MVP的model層:
接口 IShowXrecyclerViewp1 :

public interface IShowXrecyclerViewp1 {
    void showData(int type,Callback callback);
}

model類

public class ShowXrecyclerViewp1 implements IShowXrecyclerViewp1 {
    @Override
    public void showData(int type,Callback callback) {
        OkHttpUtils.getInstance().doGet("http://news-at.zhihu.com/api/4/news/before/"+type+"",callback);

    }
}

view層:

public interface bannerview {
   void getXrecyclerViewData(List<XrecyclerViewp1Bean.StoriesBean> listx);
    int getID();
}

presenter層:

public class XrecyclerViewp1Presenter  {
    Context context;
    IShowXrecyclerViewp1 model;
    bannerview view;
    private List<XrecyclerViewp1Bean.StoriesBean> listx;
    public XrecyclerViewp1Presenter(Context context,bannerview view){
        this.context=context;
        this.view=view;
        model=new ShowXrecyclerViewp1();

    }
    public void showXrecyclerViewData(){
        int type=view.getID();
       model.showData(type, new OnUiCallback() {
           @Override
           public void onFailed(Call call, IOException e) {

           }

           @Override
           public void onSuccess(String result) throws IOException {
                       Gson gson = new Gson();
                       XrecyclerViewp1Bean x = gson.fromJson(result, XrecyclerViewp1Bean.class);
                       listx=x.getStories();
                       view.getXrecyclerViewData(listx);
           }
       });
    }
}

看看它的adapter類:

public class XrecyclerViewp4adapter extends XRecyclerView.Adapter<XrecyclerViewp4adapter.MyViewHolder>  {
    Context context;
    List<RecyclerViewp4Bean.OthersBean> listg;
    public XrecyclerViewp4adapter(Context context,List<RecyclerViewp4Bean.OthersBean> listg){
        this.context=context;
        this.listg=listg;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view=View.inflate(context,R.layout.grideitem,null);
        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.tvp4.setText(listg.get(position).getName());
        ImageLoader.getInstance().displayImage(listg.get(position).getThumbnail(),holder.ivp4);
    }

    @Override
    public int getItemCount() {
        return listg==null?0:listg.size();
    }

    class MyViewHolder extends XRecyclerView.ViewHolder{
        ImageView ivp4;
        TextView tvp4;
        public MyViewHolder(View itemView) {
            super(itemView);
            tvp4=itemView.findViewById(R.id.tvg);
            ivp4=itemView.findViewById(R.id.ivg);
        }
    }
}

最后在fragment里面實現(xiàn)---showData()方法是刷新功能:

public class Fragmentzxrb extends Fragment implements bannerview {
    View view;
    private ViewPager mVprb;
    Banner bb;
    bannerpresenter presenter;
    XrecyclerViewp1Adapter xrecyclerViewp1Adapter;
    XrecyclerViewp1Presenter presenterx;
    List<String> listm;
    XRecyclerView rv;
    int type=20131119;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = View.inflate(getActivity(), R.layout.fragmentzxrb, null);
        initView();
        presenter=new bannerpresenter(getActivity(),this);
        presenterx=new XrecyclerViewp1Presenter(getActivity(),this);
        presenter.showbanner();
        presenterx.showXrecyclerViewData();
        showData();
        return view;
    }

    private void showData() {
        rv.setLoadingListener(new XRecyclerView.LoadingListener() {
            @Override
            public void onRefresh() {
                type++;
                presenterx.showXrecyclerViewData();
                xrecyclerViewp1Adapter.notifyDataSetChanged();
                rv.refreshComplete();
            }

            @Override
            public void onLoadMore() {
                type++;
                presenterx.showXrecyclerViewData();
                xrecyclerViewp1Adapter.notifyDataSetChanged();
                rv.refreshComplete();
            }
        });
    }

    private void initView() {
       rv=view.findViewById(R.id.rv);
        LinearLayoutManager layoutManager=new LinearLayoutManager(getActivity());
        rv.setLayoutManager(layoutManager);
        rv.addItemDecoration(new DividerItemDecoration(getActivity(),DividerItemDecoration.VERTICAL));
        bb=view.findViewById(R.id.bb);
        listm=new ArrayList<>();
    }

    @Override
    public void getbannerData(List<BannerBean.TopStoriesBean> listb) {
        for(int i=0;i<listb.size();i++){
            listm.add(listb.get(i).getImage());
        }
        bb.setImageLoader(new ImageLoaderBanner());
        bb.setImages(listm);
        bb.start();
    }

    @Override
    public void getXrecyclerViewData(List<XrecyclerViewp1Bean.StoriesBean> listx) {
        xrecyclerViewp1Adapter = new XrecyclerViewp1Adapter(getActivity(), listx);
        rv.setAdapter(xrecyclerViewp1Adapter);
    }

    @Override
    public int getID() {
        return type;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,023評論 25 709
  • 碼字 字的背后是一個活生生的靈魂 摻不了水打不了膠 透過他的字 你看到了字背后那個靈魂的層次 品到了靈魂深處的那份...
    靜心獨舞閱讀 125評論 0 0
  • 1.配置插件 把hadoop-eclipse-plugin-1.2.1.jar拷貝到eclipse的plugins...
    王書劍閱讀 1,113評論 0 2
  • 地上的草兒問天空: “什么是快樂?” 天空回答說: “快樂是一個小寶寶?!?大地問大海: “什么是快樂?” 大?;?..
    韋心草閱讀 647評論 0 2
  • steps toward the glory of RESTA model (developed by Leona...
    大漠狼道閱讀 492評論 0 1

友情鏈接更多精彩內(nèi)容