<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2
2
 
1
    <uses-permission android:name="android.permission.INTERNET"/>
2
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

依赖

注:这里没有指定支持 Lambda 表达式需要的配置
    //【retrofit2】
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0' //【okhttp】
compile 'com.squareup.okhttp3:okhttp:3.8.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
compile 'com.squareup.okio:okio:1.13.0' //【butterknife】
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' //【rxjava】
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.6'
17
17
 
1
    //【retrofit2】
2
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
3
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
4
    compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
5

6
    //【okhttp】
7
    compile 'com.squareup.okhttp3:okhttp:3.8.0'
8
    compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
9
    compile 'com.squareup.okio:okio:1.13.0'
10

11
    //【butterknife】
12
    compile 'com.jakewharton:butterknife:8.8.1'
13
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
14

15
    //【rxjava】
16
    compile 'io.reactivex:rxandroid:1.1.0'
17
    compile 'io.reactivex:rxjava:1.1.6'

GitHubApi

public interface GitHubApi {

	@GET("repos/{owner}/{repo}/contributors")
Call<ResponseBody> contributorsBySimpleGetCall(@Path("owner") String owner, @Path("repo") String repo); @GET("repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributorsByAddConverterGetCall(@Path("owner") String owner, @Path("repo") String repo); @Headers({"Accept: application/vnd.github.v3.full+json", "User-Agent: RetrofitBean-Sample-App", "name:ljd"})
@GET("repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributorsAndAddHeader(@Path("owner") String owner, @Path("repo") String repo); @GET("search/repositories")
Call<RetrofitBean> queryRetrofitByGetCall(@Query("q") String owner, @Query("since") String time, @Query("page") int page, @Query("per_page") int per_Page); @GET("search/repositories")
Call<RetrofitBean> queryRetrofitByGetCallMap(@QueryMap Map<String, String> map); @GET("repos/{owner}/{repo}/contributors")
Observable<List<Contributor>> contributorsByRxJava(@Path("owner") String owner, @Path("repo") String repo); @GET("users/{user}")
Observable<User> userByRxJava(@Path("user") String user); @GET("/mobilesafe/shouji360/360safesis/360MobileSafe_6.2.3.1060.apk")
Call<ResponseBody> retrofitDownload();
}
27
27
 
1
public interface GitHubApi {
2
    
3
    @GET("repos/{owner}/{repo}/contributors")
4
    Call<ResponseBody> contributorsBySimpleGetCall(@Path("owner") String owner, @Path("repo") String repo);
5
    
6
    @GET("repos/{owner}/{repo}/contributors")
7
    Call<List<Contributor>> contributorsByAddConverterGetCall(@Path("owner") String owner, @Path("repo") String repo);
8
    
9
    @Headers({"Accept: application/vnd.github.v3.full+json", "User-Agent: RetrofitBean-Sample-App", "name:ljd"})
10
    @GET("repos/{owner}/{repo}/contributors")
11
    Call<List<Contributor>> contributorsAndAddHeader(@Path("owner") String owner, @Path("repo") String repo);
12
    
13
    @GET("search/repositories")
14
    Call<RetrofitBean> queryRetrofitByGetCall(@Query("q") String owner, @Query("since") String time, @Query("page") int page, @Query("per_page") int per_Page);
15
    
16
    @GET("search/repositories")
17
    Call<RetrofitBean> queryRetrofitByGetCallMap(@QueryMap Map<String, String> map);
18
    
19
    @GET("repos/{owner}/{repo}/contributors")
20
    Observable<List<Contributor>> contributorsByRxJava(@Path("owner") String owner, @Path("repo") String repo);
21
    
22
    @GET("users/{user}")
23
    Observable<User> userByRxJava(@Path("user") String user);
24
    
25
    @GET("/mobilesafe/shouji360/360safesis/360MobileSafe_6.2.3.1060.apk")
26
    Call<ResponseBody> retrofitDownload();
27
}

MainActivity

public class MainActivity extends ListActivity {
private TextView tv;
private static final String baseUrl = "https://api.github.com/";
private static final String mUserName = "square";//哪个公司【square】
private static final String mRepo = "retrofit";//哪个项目【retrofit】
private CompositeSubscription mSubscriptions = new CompositeSubscription(); protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"1、简单完整演示retrofit的使用",
"2、添加Gson转换器",
"3、添加okHttp的日志拦截器Interceptor",
"4、使用自己封装的API,演示@Headers",
"5、演示同步请求",
"6、演示@Query",
"7、演示@QueryMap",
"8、最简单、完整的retrofit+rxJava示例",
"9、rxJava+retrofit增强",
"10、演示文件下载",};
tv = new TextView(this);// 将内容显示在TextView中
tv.setTextColor(Color.BLUE);
getListView().addFooterView(tv);
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new ArrayList<>(Arrays.asList(array))));
} @Override
protected void onDestroy() {
if (mSubscriptions != null) mSubscriptions.unsubscribe();
super.onDestroy();
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
switch (position + 1) {
case 1://简单完整演示retrofit的使用
requestGitHubContributorsSimple();
break;
case 2://添加Gson转换器
requestGitHubContributorsByConverter();
break;
case 3://添加okHttp的日志拦截器Interceptor
requestGitHubContributorsAddOkHttpLog();
break;
case 4://使用自己封装的API,演示@Headers
requestGitHubContributorsAddHeader();
break;
case 5://演示同步请求
requestGitHubContributorsBySync();
break;
case 6://演示@Query
requestQueryRetrofitByGet(false);
break;
case 7://演示@QueryMap
requestQueryRetrofitByGet(true);
break;
case 8://最简单、完整的retrofit+rxJava示例
requestGitHubContributorsByRxJava();
break;
case 9://rxJava+retrofit增强
requestGitHubContributorsWithFullUserInfo();
break;
case 10://演示文件下载
retrofitDownload();
break;
}
} /**
* 1、简单示例
*/
private void requestGitHubContributorsSimple() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.build();
GitHubApi repo = retrofit.create(GitHubApi.class);
Call<ResponseBody> call = repo.contributorsBySimpleGetCall(mUserName, mRepo);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
String result = null;
try {
result = response.body().string();
if (result == null) return;
} catch (IOException e) {
e.printStackTrace();
}
tv.setText("GitHub上对项目的贡献-1:\n");
ArrayList<Contributor> list = new Gson()
.fromJson(result, new TypeToken<List<Contributor>>() {
}.getType());
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
} @Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} /**
* 2、添加Gson转换器
*/
private void requestGitHubContributorsByConverter() {
new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())//转换器
.build()
.create(GitHubApi.class)
.contributorsByAddConverterGetCall(mUserName, mRepo)
.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<Contributor>> response) {
List<Contributor> list = response.body();
tv.setText("GitHub上对项目的贡献-2:\n");
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
} @Override
public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} /**
* 3、添加okHttp的日志拦截器Interceptor
*/
private void requestGitHubContributorsAddOkHttpLog() {
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY); Retrofit retrofit = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(new OkHttpClient.Builder().addInterceptor(logInterceptor).build())
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build(); retrofit.create(GitHubApi.class)
.contributorsByAddConverterGetCall(mUserName, mRepo)
.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<com.bqt
.retrofit.bean.Contributor>> response) {
List<Contributor> list = response.body();
tv.setText("GitHub上对项目的贡献-3:\n");
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
} @Override
public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} /**
* 4、使用自己封装的API,演示@Headers
*/
private void requestGitHubContributorsAddHeader() {
createRetrofitService(GitHubApi.class)
.contributorsAndAddHeader(mUserName, mRepo)
.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<com.bqt
.retrofit.bean.Contributor>> response) {
List<Contributor> list = response.body();
tv.setText("GitHub上对项目的贡献-4:\n");
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
} @Override
public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
}
});
} /**
* 5、演示同步请求
*/
private void requestGitHubContributorsBySync() {
final Call<List<Contributor>> call = createRetrofitService(GitHubApi.class)
.contributorsByAddConverterGetCall(mUserName, mRepo);
new Thread(() -> {
try {
Response<List<Contributor>> response = call.execute();//在子线程中请求网络
final List<Contributor> list = response.body();
runOnUiThread(() -> {
tv.setText("GitHub上对项目的贡献-5:\n");
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
});
} catch (IOException e) {
e.printStackTrace();
}
}).start();
} /**
* 6/7、演示@Query和@QueryMap
*/
private void requestQueryRetrofitByGet(boolean isQueryMap) {
GitHubApi mGitHubService = createRetrofitService(GitHubApi.class);
Call<RetrofitBean> call;
if (!isQueryMap) call = mGitHubService.queryRetrofitByGetCall("retrofit", "2016-03-29", 1, 3);
else {
Map<String, String> queryMap = new HashMap<>();
queryMap.put("q", "retrofit");
queryMap.put("since", "2016-03-29");
queryMap.put("page", "1");
queryMap.put("per_page", "3");
call = mGitHubService.queryRetrofitByGetCallMap(queryMap);
} call.enqueue(new Callback<RetrofitBean>() {
@Override
public void onResponse(@NonNull Call<RetrofitBean> call, @NonNull Response<RetrofitBean> response) {
RetrofitBean retrofitBean = response.body();
if (retrofitBean == null) return;
List<Item> list = retrofitBean.getItems();
if (list == null || list.size() == 0) return; tv.setText(new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date()));
tv.append("\ntotal:" + retrofitBean.getTotalCount() + "\nincompleteResults:" + retrofitBean.getIncompleteResults());
for (Item item : list) {
tv.append("\n\n【name】" + item.name);
tv.append("\n【full_name】" + item.full_name);
tv.append("\n【 description】" + item.description);
}
} @Override
public void onFailure(@NonNull Call<RetrofitBean> call, @NonNull Throwable t) {
}
});
} /**
* 8、最简单、完整的retrofit+rxJava示例
*/
private void requestGitHubContributorsByRxJava() {
createRetrofitService(GitHubApi.class)
.contributorsByRxJava(mUserName, mRepo)//
.subscribeOn(Schedulers.io())//
.observeOn(AndroidSchedulers.mainThread())//
.subscribe(new Observer<List<Contributor>>() {
@Override
public void onCompleted() {
Toast.makeText(MainActivity.this, "完成", Toast.LENGTH_SHORT).show();
} @Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
} @Override
public void onNext(List<Contributor> list) {
tv.setText("GitHub上对项目的贡献-8:\n");
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
}
});
} /**
* 9、rxJava+retrofit增强
*/
private void requestGitHubContributorsWithFullUserInfo() {
tv.setText("");
final GitHubApi mGitHubService = createRetrofitService(GitHubApi.class); Subscription subscription =
mGitHubService.contributorsByRxJava(mUserName, mRepo)//
.flatMap(new Func1<List<Contributor>, Observable<Contributor>>() {
//变换:将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列
@Override
public Observable<Contributor> call(List<Contributor>
contributors) {
//1、使用传入的事件对象创建一个 Observable 对象;
//2、并不发送这个 Observable,而是将它激活,于是它开始发送事件;
//3、创建的 Observable 发送的事件,都被汇入同一个 Observable,而这个 Observable 负责将这些事件统一交给Subscriber 的回调方法
return Observable.from(contributors);
}
})
.flatMap(new Func1<Contributor, Observable<Pair<User, Contributor>>>() {
@Override
public Observable<Pair<User, Contributor>> call(com.bqt
.retrofit.bean.Contributor contributor) {
Observable<User> userObservable = mGitHubService.userByRxJava(contributor.login)
.filter(user -> !isEmpty(user.name) && !isEmpty(user.email));
return Observable.zip(userObservable, Observable.just(contributor), Pair::new);
}
})
.subscribeOn(Schedulers.newThread())//指定 subscribe() 发生在哪个线程,后台线程取数据,主线程显示
.observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 的回调发生在主线程
.subscribe(new Observer<Pair<User, Contributor>>() {
@Override
public void onCompleted() {
Toast.makeText(MainActivity.this, "完成", Toast.LENGTH_SHORT).show();
} @Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
} @Override
public void onNext(Pair<User, Contributor> pair) {
User user = pair.first;
Contributor contributor = pair.second;
tv.append("name:" + user.name + "\ncontributions:" + contributor.contributions + "\nEmail:" + user.email + "\n\n");
}
});
mSubscriptions.add(subscription);
} /**
* 10、演示文件下载
*/
public void retrofitDownload() {
//监听下载进度
final ProgressDialog dialog = new ProgressDialog(this);
dialog.setProgressNumberFormat("%1d KB/%2d KB");
dialog.setTitle("下载");
dialog.setMessage("正在下载,请稍后...");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false);
dialog.show(); ProgressHelper.setProgressHandler(new DownloadProgressHandler() {
@Override
protected void onProgress(long bytesRead, long contentLength, boolean done) {
//在主线程中运行
dialog.setMax((int) (contentLength / 1024));
dialog.setProgress((int) (bytesRead / 1024));
if (done) dialog.dismiss();
}
}); Retrofit retrofit = new Retrofit.Builder()//
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//
.addConverterFactory(GsonConverterFactory.create())//
.baseUrl("http://msoftdl.360.cn")
.client(ProgressHelper.addProgress(null).build())
.build(); retrofit.create(GitHubApi.class).retrofitDownload()
.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
try {
InputStream is = response.body().byteStream();
File file = new File(Environment.getExternalStorageDirectory(), "12345.apk");
FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
fos.flush();
}
fos.close();
bis.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
}
});
} public static <T> T createRetrofitService(final Class<T> service) {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor);
Retrofit retrofit = new Retrofit.Builder()//
.client(ProgressHelper.addProgress(builder).build())//
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//
.addConverterFactory(GsonConverterFactory.create())//
.baseUrl("https://api.github.com/")//
.build();
return retrofit.create(service);
}
}
403
403
 
1
public class MainActivity extends ListActivity {
2
    private TextView tv;
3
    private static final String baseUrl = "https://api.github.com/";
4
    private static final String mUserName = "square";//哪个公司【square】
5
    private static final String mRepo = "retrofit";//哪个项目【retrofit】
6
    private CompositeSubscription mSubscriptions = new CompositeSubscription();
7
    
8
    protected void onCreate(Bundle savedInstanceState) {
9
        super.onCreate(savedInstanceState);
10
        String[] array = {"1、简单完整演示retrofit的使用",
11
                "2、添加Gson转换器",
12
                "3、添加okHttp的日志拦截器Interceptor",
13
                "4、使用自己封装的API,演示@Headers",
14
                "5、演示同步请求",
15
                "6、演示@Query",
16
                "7、演示@QueryMap",
17
                "8、最简单、完整的retrofit+rxJava示例",
18
                "9、rxJava+retrofit增强",
19
                "10、演示文件下载",};
20
        tv = new TextView(this);// 将内容显示在TextView中
21
        tv.setTextColor(Color.BLUE);
22
        getListView().addFooterView(tv);
23
        setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new ArrayList<>(Arrays.asList(array))));
24
    }
25
    
26
    @Override
27
    protected void onDestroy() {
28
        if (mSubscriptions != null) mSubscriptions.unsubscribe();
29
        super.onDestroy();
30
    }
31
    
32
    @Override
33
    protected void onListItemClick(ListView l, View v, int position, long id) {
34
        switch (position + 1) {
35
            case 1://简单完整演示retrofit的使用
36
                requestGitHubContributorsSimple();
37
                break;
38
            case 2://添加Gson转换器
39
                requestGitHubContributorsByConverter();
40
                break;
41
            case 3://添加okHttp的日志拦截器Interceptor
42
                requestGitHubContributorsAddOkHttpLog();
43
                break;
44
            case 4://使用自己封装的API,演示@Headers
45
                requestGitHubContributorsAddHeader();
46
                break;
47
            case 5://演示同步请求
48
                requestGitHubContributorsBySync();
49
                break;
50
            case 6://演示@Query
51
                requestQueryRetrofitByGet(false);
52
                break;
53
            case 7://演示@QueryMap
54
                requestQueryRetrofitByGet(true);
55
                break;
56
            case 8://最简单、完整的retrofit+rxJava示例
57
                requestGitHubContributorsByRxJava();
58
                break;
59
            case 9://rxJava+retrofit增强
60
                requestGitHubContributorsWithFullUserInfo();
61
                break;
62
            case 10://演示文件下载
63
                retrofitDownload();
64
                break;
65
        }
66
    }
67
    
68
    /**
69
     * 1、简单示例
70
     */
71
    private void requestGitHubContributorsSimple() {
72
        Retrofit retrofit = new Retrofit.Builder()
73
                .baseUrl(baseUrl)
74
                .build();
75
        GitHubApi repo = retrofit.create(GitHubApi.class);
76
        Call<ResponseBody> call = repo.contributorsBySimpleGetCall(mUserName, mRepo);
77
        call.enqueue(new Callback<ResponseBody>() {
78
            @Override
79
            public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
80
                String result = null;
81
                try {
82
                    result = response.body().string();
83
                    if (result == null) return;
84
                } catch (IOException e) {
85
                    e.printStackTrace();
86
                }
87
                tv.setText("GitHub上对项目的贡献-1:\n");
88
                ArrayList<Contributor> list = new Gson()
89
                        .fromJson(result, new TypeToken<List<Contributor>>() {
90
                        }.getType());
91
                if (list == null || list.size() == 0) return;
92
                for (Contributor contributor : list) {
93
                    tv.append(contributor.login + "    " + contributor.contributions + "\n");
94
                }
95
            }
96
            
97
            @Override
98
            public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
99
                Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
100
            }
101
        });
102
    }
103
    
104
    /**
105
     * 2、添加Gson转换器
106
     */
107
    private void requestGitHubContributorsByConverter() {
108
        new Retrofit.Builder()
109
                .baseUrl(baseUrl)
110
                .addConverterFactory(GsonConverterFactory.create())//转换器
111
                .build()
112
                .create(GitHubApi.class)
113
                .contributorsByAddConverterGetCall(mUserName, mRepo)
114
                .enqueue(new Callback<List<Contributor>>() {
115
                    @Override
116
                    public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<Contributor>> response) {
117
                        List<Contributor> list = response.body();
118
                        tv.setText("GitHub上对项目的贡献-2:\n");
119
                        if (list == null || list.size() == 0) return;
120
                        for (Contributor contributor : list) {
121
                            tv.append(contributor.login + "    " + contributor.contributions + "\n");
122
                        }
123
                    }
124
                    
125
                    @Override
126
                    public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
127
                        Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
128
                    }
129
                });
130
    }
131
    
132
    /**
133
     * 3、添加okHttp的日志拦截器Interceptor
134
     */
135
    private void requestGitHubContributorsAddOkHttpLog() {
136
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
137
        
138
        Retrofit retrofit = new Retrofit.Builder()
139
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
140
                .client(new OkHttpClient.Builder().addInterceptor(logInterceptor).build())
141
                .baseUrl(baseUrl)
142
                .addConverterFactory(GsonConverterFactory.create())
143
                .build();
144
        
145
        retrofit.create(GitHubApi.class)
146
                .contributorsByAddConverterGetCall(mUserName, mRepo)
147
                .enqueue(new Callback<List<Contributor>>() {
148
                    @Override
149
                    public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<com.bqt
150
                            .retrofit.bean.Contributor>> response) {
151
                        List<Contributor> list = response.body();
152
                        tv.setText("GitHub上对项目的贡献-3:\n");
153
                        if (list == null || list.size() == 0) return;
154
                        for (Contributor contributor : list) {
155
                            tv.append(contributor.login + "    " + contributor.contributions + "\n");
156
                        }
157
                    }
158
                    
159
                    @Override
160
                    public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
161
                        Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
162
                    }
163
                });
164
    }
165
    
166
    /**
167
     * 4、使用自己封装的API,演示@Headers
168
     */
169
    private void requestGitHubContributorsAddHeader() {
170
        createRetrofitService(GitHubApi.class)
171
                .contributorsAndAddHeader(mUserName, mRepo)
172
                .enqueue(new Callback<List<Contributor>>() {
173
                    @Override
174
                    public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<com.bqt
175
                            .retrofit.bean.Contributor>> response) {
176
                        List<Contributor> list = response.body();
177
                        tv.setText("GitHub上对项目的贡献-4:\n");
178
                        if (list == null || list.size() == 0) return;
179
                        for (Contributor contributor : list) {
180
                            tv.append(contributor.login + "    " + contributor.contributions + "\n");
181
                        }
182
                    }
183
                    
184
                    @Override
185
                    public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
186
                    }
187
                });
188
    }
189
    
190
    /**
191
     * 5、演示同步请求
192
     */
193
    private void requestGitHubContributorsBySync() {
194
        final Call<List<Contributor>> call = createRetrofitService(GitHubApi.class)
195
                .contributorsByAddConverterGetCall(mUserName, mRepo);
196
        new Thread(() -> {
197
            try {
198
                Response<List<Contributor>> response = call.execute();//在子线程中请求网络
199
                final List<Contributor> list = response.body();
200
                runOnUiThread(() -> {
201
                    tv.setText("GitHub上对项目的贡献-5:\n");
202
                    for (Contributor contributor : list) {
203
                        tv.append(contributor.login + "    " + contributor.contributions + "\n");
204
                    }
205
                });
206
            } catch (IOException e) {
207
                e.printStackTrace();
208
            }
209
        }).start();
210
    }
211
    
212
    /**
213
     * 6/7、演示@Query和@QueryMap
214
     */
215
    private void requestQueryRetrofitByGet(boolean isQueryMap) {
216
        GitHubApi mGitHubService = createRetrofitService(GitHubApi.class);
217
        Call<RetrofitBean> call;
218
        if (!isQueryMap) call = mGitHubService.queryRetrofitByGetCall("retrofit", "2016-03-29", 1, 3);
219
        else {
220
            Map<String, String> queryMap = new HashMap<>();
221
            queryMap.put("q", "retrofit");
222
            queryMap.put("since", "2016-03-29");
223
            queryMap.put("page", "1");
224
            queryMap.put("per_page", "3");
225
            call = mGitHubService.queryRetrofitByGetCallMap(queryMap);
226
        }
227
        
228
        call.enqueue(new Callback<RetrofitBean>() {
229
            @Override
230
            public void onResponse(@NonNull Call<RetrofitBean> call, @NonNull Response<RetrofitBean> response) {
231
                RetrofitBean retrofitBean = response.body();
232
                if (retrofitBean == null) return;
233
                List<Item> list = retrofitBean.getItems();
234
                if (list == null || list.size() == 0) return;
235
                
236
                tv.setText(new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date()));
237
                tv.append("\ntotal:" + retrofitBean.getTotalCount() + "\nincompleteResults:" + retrofitBean.getIncompleteResults());
238
                for (Item item : list) {
239
                    tv.append("\n\n【name】" + item.name);
240
                    tv.append("\n【full_name】" + item.full_name);
241
                    tv.append("\n【 description】" + item.description);
242
                }
243
            }
244
            
245
            @Override
246
            public void onFailure(@NonNull Call<RetrofitBean> call, @NonNull Throwable t) {
247
            }
248
        });
249
    }
250
    
251
    /**
252
     * 8、最简单、完整的retrofit+rxJava示例
253
     */
254
    private void requestGitHubContributorsByRxJava() {
255
        createRetrofitService(GitHubApi.class)
256
                .contributorsByRxJava(mUserName, mRepo)//
257
                .subscribeOn(Schedulers.io())//
258
                .observeOn(AndroidSchedulers.mainThread())//
259
                .subscribe(new Observer<List<Contributor>>() {
260
                    @Override
261
                    public void onCompleted() {
262
                        Toast.makeText(MainActivity.this, "完成", Toast.LENGTH_SHORT).show();
263
                    }
264
                    
265
                    @Override
266
                    public void onError(Throwable e) {
267
                        Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
268
                    }
269
                    
270
                    @Override
271
                    public void onNext(List<Contributor> list) {
272
                        tv.setText("GitHub上对项目的贡献-8:\n");
273
                        for (Contributor contributor : list) {
274
                            tv.append(contributor.login + "    " + contributor.contributions + "\n");
275
                        }
276
                    }
277
                });
278
    }
279
    
280
    /**
281
     * 9、rxJava+retrofit增强
282
     */
283
    private void requestGitHubContributorsWithFullUserInfo() {
284
        tv.setText("");
285
        final GitHubApi mGitHubService = createRetrofitService(GitHubApi.class);
286
        
287
        Subscription subscription =
288
                mGitHubService.contributorsByRxJava(mUserName, mRepo)//
289
                        .flatMap(new Func1<List<Contributor>, Observable<Contributor>>() {
290
                            //变换:将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列
291
                            @Override
292
                            public Observable<Contributor> call(List<Contributor>
293
                                                                        contributors) {
294
                                //1、使用传入的事件对象创建一个 Observable 对象;
295
                                //2、并不发送这个 Observable,而是将它激活,于是它开始发送事件;
296
                                //3、创建的 Observable 发送的事件,都被汇入同一个 Observable,而这个 Observable 负责将这些事件统一交给Subscriber 的回调方法
297
                                return Observable.from(contributors);
298
                            }
299
                        })
300
                        .flatMap(new Func1<Contributor, Observable<Pair<User, Contributor>>>() {
301
                            @Override
302
                            public Observable<Pair<User, Contributor>> call(com.bqt
303
                                                                                    .retrofit.bean.Contributor contributor) {
304
                                Observable<User> userObservable = mGitHubService.userByRxJava(contributor.login)
305
                                        .filter(user -> !isEmpty(user.name) && !isEmpty(user.email));
306
                                return Observable.zip(userObservable, Observable.just(contributor), Pair::new);
307
                            }
308
                        })
309
                        .subscribeOn(Schedulers.newThread())//指定 subscribe() 发生在哪个线程,后台线程取数据,主线程显示
310
                        .observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 的回调发生在主线程
311
                        .subscribe(new Observer<Pair<User, Contributor>>() {
312
                            @Override
313
                            public void onCompleted() {
314
                                Toast.makeText(MainActivity.this, "完成", Toast.LENGTH_SHORT).show();
315
                            }
316
                            
317
                            @Override
318
                            public void onError(Throwable e) {
319
                                Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
320
                            }
321
                            
322
                            @Override
323
                            public void onNext(Pair<User, Contributor> pair) {
324
                                User user = pair.first;
325
                                Contributor contributor = pair.second;
326
                                tv.append("name:" + user.name + "\ncontributions:" + contributor.contributions + "\nEmail:" + user.email + "\n\n");
327
                            }
328
                        });
329
        mSubscriptions.add(subscription);
330
    }
331
    
332
    /**
333
     * 10、演示文件下载
334
     */
335
    public void retrofitDownload() {
336
        //监听下载进度
337
        final ProgressDialog dialog = new ProgressDialog(this);
338
        dialog.setProgressNumberFormat("%1d KB/%2d KB");
339
        dialog.setTitle("下载");
340
        dialog.setMessage("正在下载,请稍后...");
341
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
342
        dialog.setCancelable(false);
343
        dialog.show();
344
        
345
        ProgressHelper.setProgressHandler(new DownloadProgressHandler() {
346
            @Override
347
            protected void onProgress(long bytesRead, long contentLength, boolean done) {
348
                //在主线程中运行
349
                dialog.setMax((int) (contentLength / 1024));
350
                dialog.setProgress((int) (bytesRead / 1024));
351
                if (done) dialog.dismiss();
352
            }
353
        });
354
        
355
        Retrofit retrofit = new Retrofit.Builder()//
356
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//
357
                .addConverterFactory(GsonConverterFactory.create())//
358
                .baseUrl("http://msoftdl.360.cn")
359
                .client(ProgressHelper.addProgress(null).build())
360
                .build();
361
        
362
        retrofit.create(GitHubApi.class).retrofitDownload()
363
                .enqueue(new Callback<ResponseBody>() {
364
                    @Override
365
                    public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
366
                        try {
367
                            InputStream is = response.body().byteStream();
368
                            File file = new File(Environment.getExternalStorageDirectory(), "12345.apk");
369
                            FileOutputStream fos = new FileOutputStream(file);
370
                            BufferedInputStream bis = new BufferedInputStream(is);
371
                            byte[] buffer = new byte[1024];
372
                            int len;
373
                            while ((len = bis.read(buffer)) != -1) {
374
                                fos.write(buffer, 0, len);
375
                                fos.flush();
376
                            }
377
                            fos.close();
378
                            bis.close();
379
                            is.close();
380
                        } catch (IOException e) {
381
                            e.printStackTrace();
382
                        }
383
                    }
384
                    
385
                    @Override
386
                    public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
387
                    }
388
                });
389
    }
390
    
391
    public static <T> T createRetrofitService(final Class<T> service) {
392
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor()
393
            .setLevel(HttpLoggingInterceptor.Level.BODY);
394
        OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor);
395
        Retrofit retrofit = new Retrofit.Builder()//
396
                .client(ProgressHelper.addProgress(builder).build())//
397
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//
398
                .addConverterFactory(GsonConverterFactory.create())//
399
                .baseUrl("https://api.github.com/")//
400
                .build();
401
        return retrofit.create(service);
402
    }
403
}

综合配置

retrofit、okhttp、RxJava、Gson、拦截器、Header等配置
public class H {
private static Interceptor buildInterceptor() {
final String token = AccountManager.getInstance().getToken();
PackageInfo packInfo = null;
try {
packInfo = App.app.getPackageManager().getPackageInfo(App.app.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
final int version = packInfo == null ? 1 : packInfo.versionCode;
return new Interceptor() {//应用程序拦截器,只被调用一次
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
.addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("Connection", "keep-alive")
.addHeader("Accept", "*/*")
//****************************************自定义Header**************************************************
.addHeader("version", version + "")//app版本号
.addHeader("token", token == null ? "" : token)//登录后返回的token
.addHeader("mobile", "1")// 0-PC,1-Android,2-IOS,3-web
.build();
return chain.proceed(request);
}
};
} private static Interceptor buildLogInterceptor() {
return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
L.i(message);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY);//日志显示级别
} private static OkHttpClient buildOkHttp() {
return new OkHttpClient.Builder()
.addInterceptor(buildHeaderInterceptor())//自定义Header
.addInterceptor(buildLogInterceptor())//日志拦截
.connectTimeout(5, TimeUnit.SECONDS)
.build();
} private static Gson buildGson() {
return new GsonBuilder()//配置你的Gson
.setDateFormat("yyyy-MM-dd hh:mm:ss")
.setPrettyPrinting()
.serializeNulls()
.create();
} private static String buildBaseUrl() {
switch (UrlHelper.getEnv()) {
case 0: // baseUlr 必须以 / 结束,不然会抛出一个IllegalArgumentException
return "http://test.talk.99cj.com.cn/";
case 1:
return "http://wechat.99cj.com.cn/";
default:
return "http://wechat.99cj.com.cn/";
}
} private static Retrofit buildRetrofit(OkHttpClient client, Converter.Factory converterFactory, CallAdapter.Factory callAdapterFactory) {
return new Retrofit.Builder()
.baseUrl(buildBaseUrl())
.client(client)
.addConverterFactory(converterFactory)//可以接收自定义的Gson,当然也可以不传
.addCallAdapterFactory(callAdapterFactory)
.build();
} private static <T> T createRetrofitService(final Class<T> service) {
Retrofit retrofit = buildRetrofit(buildOkHttp(), //
GsonConverterFactory.create(buildGson()),//
RxJavaCallAdapterFactory.create());//
return retrofit.create(service);
} public static BqtService h() {
return createRetrofitService(BqtService.class);
}
}
x
 
1
public class H {
2
    private static Interceptor buildInterceptor() {
3
        final String token = AccountManager.getInstance().getToken();
4
        PackageInfo packInfo = null;
5
        try {
6
            packInfo = App.app.getPackageManager().getPackageInfo(App.app.getPackageName(), 0);
7
        } catch (PackageManager.NameNotFoundException e) {
8
            e.printStackTrace();
9
        }
10
        final int version = packInfo == null ? 1 : packInfo.versionCode;
11
        return new Interceptor() {//应用程序拦截器,只被调用一次
12
            @Override
13
            public okhttp3.Response intercept(Chain chain) throws IOException {
14
                Request request = chain.request()
15
                        .newBuilder()
16
                        .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
17
                        .addHeader("Accept-Encoding", "gzip, deflate")
18
                        .addHeader("Connection", "keep-alive")
19
                        .addHeader("Accept", "*/*")
20
                        //****************************************自定义Header**************************************************
21
                        .addHeader("version", version + "")//app版本号
22
                        .addHeader("token", token == null ? "" : token)//登录后返回的token
23
                        .addHeader("mobile", "1")// 0-PC,1-Android,2-IOS,3-web
24
                        .build();
25
                return chain.proceed(request);
26
            }
27
        };
28
    }
29
    
30
    private static Interceptor buildLogInterceptor() {
31
        return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
32
            @Override
33
            public void log(String message) {
34
                L.i(message);
35
            }
36
        }).setLevel(HttpLoggingInterceptor.Level.BODY);//日志显示级别
37
    }
38
    
39
    private static OkHttpClient buildOkHttp() {
40
        return new OkHttpClient.Builder()
41
                .addInterceptor(buildHeaderInterceptor())//自定义Header
42
                .addInterceptor(buildLogInterceptor())//日志拦截
43
                .connectTimeout(5, TimeUnit.SECONDS)
44
                .build();
45
    }
46
    
47
    private static Gson buildGson() {
48
        return new GsonBuilder()//配置你的Gson
49
                .setDateFormat("yyyy-MM-dd hh:mm:ss")
50
                .setPrettyPrinting()
51
                .serializeNulls()
52
                .create();
53
    }
54
    
55
    private static String buildBaseUrl() {
56
        switch (UrlHelper.getEnv()) {
57
            case 0: // baseUlr 必须以 / 结束,不然会抛出一个IllegalArgumentException
58
                return "http://test.talk.99cj.com.cn/";
59
            case 1:
60
                return "http://wechat.99cj.com.cn/";
61
            default:
62
                return "http://wechat.99cj.com.cn/";
63
        }
64
    }
65
    
66
    private static Retrofit buildRetrofit(OkHttpClient client, Converter.Factory converterFactory, CallAdapter.Factory callAdapterFactory) {
67
        return new Retrofit.Builder()
68
                .baseUrl(buildBaseUrl())
69
                .client(client)
70
                .addConverterFactory(converterFactory)//可以接收自定义的Gson,当然也可以不传
71
                .addCallAdapterFactory(callAdapterFactory)
72
                .build();
73
    }
74
    
75
    private static <T> T createRetrofitService(final Class<T> service) {
76
        Retrofit retrofit = buildRetrofit(buildOkHttp(), //
77
                GsonConverterFactory.create(buildGson()),//
78
                RxJavaCallAdapterFactory.create());//
79
        return retrofit.create(service);
80
    }
81
    
82
    public static BqtService h() {
83
        return createRetrofitService(BqtService.class);
84
    }
85
}
添加上述【HttpLoggingInterceptor】拦截器后会打印如下日志
请求参数封装
public interface BqtService {
/*个人中心*/ /* 如果注解中提供的url是完整的url(以http开头),则忽略baseUrl,直接讲此url将作为请求的url */
@GET("User") /* 如果不以/开头,则请求的url为baseUrl+注解中提供的值;否则请求的url为baseUrl的主机部分+注解中提供的值*/
Observable<BqtRes<User>> getUser(); /*用户购买记录*/
@FormUrlEncoded
@POST("BuyInfo/buyRecord") /*【type】1:购买课程 2:购买观点 3:直播赞赏*/
Observable<BqtRes<ArrayList<MyClassBean>>> getPurchaseHistory1(@Field("user_id") int uid, @Field("page") int page, @Field("type") int type);
}
x
10
 
1
public interface BqtService {
2
    /*个人中心*/  /* 如果注解中提供的url是完整的url(以http开头),则忽略baseUrl,直接讲此url将作为请求的url */
3
    @GET("User") /* 如果不以/开头,则请求的url为baseUrl+注解中提供的值;否则请求的url为baseUrl的主机部分+注解中提供的值*/
4
    Observable<BqtRes<User>> getUser();
5

6
    /*用户购买记录*/
7
    @FormUrlEncoded
8
    @POST("BuyInfo/buyRecord")  /*【type】1:购买课程 2:购买观点 3:直播赞赏*/
9
    Observable<BqtRes<ArrayList<MyClassBean>>> getPurchaseHistory1(@Field("user_id") int uid, @Field("page") int page, @Field("type") int type);
10
}
调用
H.h().getUser()
.subscribeOn(Schedulers.newThread())//指定 subscribe() 发生在哪个线程,后台线程取数据,主线程显示
.observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 的回调发生在主线程
.subscribe(new Subscriber<BqtRes<User>>() {
@Override
public void onCompleted() {
} @Override
public void onError(Throwable e) {
L.i("【onError】" + e.toString());
} @Override
public void onNext(BqtRes<User> response) {
L.i("【onNext】" + response.data.toString());//这里response.data的类型即是User
}
});
18
 
1
H.h().getUser()
2
    .subscribeOn(Schedulers.newThread())//指定 subscribe() 发生在哪个线程,后台线程取数据,主线程显示
3
    .observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 的回调发生在主线程
4
    .subscribe(new Subscriber<BqtRes<User>>() {
5
        @Override
6
        public void onCompleted() {
7
        }
8
        
9
        @Override
10
        public void onError(Throwable e) {
11
            L.i("【onError】" + e.toString());
12
        }
13
        
14
        @Override
15
        public void onNext(BqtRes<User> response) {
16
            L.i("【onNext】" + response.data.toString());//这里response.data的类型即是User
17
        }
18
    });
2017-9-22

附件列表

retrofit2 okhttp3 RxJava butterknife 示例的更多相关文章

  1. Rxjava+Retrofit2+Okhttp3多文件上传(服务器端代码+客户端代码)

    所有代码亲测可用,如有问题,欢迎指正. 首先在ApiService接口文件中新建文件上传接口 public interface ApiService { static final String BAS ...

  2. [Android] Android RxJava2+Retrofit2+OkHttp3 的使用

    [Android] Android RxJava2+Retrofit2+OkHttp3 简单介绍Retrofit.OKHttp和RxJava之间的关系: Retrofit:Retrofit是Squar ...

  3. Retrofit2与RxJava用法大全

    Retrofit2是square公司出品的一个网络请求库,网上有很多相关的介绍.我很久以前都想去研究了,但一直都有各种事情耽搁,现在就让我们一起去捋一捋,这篇主要讲解Retrofit2与RxJava的 ...

  4. Retrofit2.0+RxJava+Dragger2实现不一样的Android网络架构搭建

    Tamic :csdn http://blog.csdn.net/sk719887916 众所周知,手机APP的核心就在于调用后台接口,展示相关信息,方便我们在手机上就能和外界交互.所以APP中网络框 ...

  5. Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)

    csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...

  6. 基于Retrofit2.0+RxJava+Dragger2实现不一样的Android网络构架搭建(转载)

    转载请注明出处:http://blog.csdn.net/finddreams/article/details/50849385#0-qzone-1-61707-d020d2d2a4e8d1a374a ...

  7. [Android] Android RxJava2+Retrofit2+OkHttp3 的使用(一) --基础篇 Retrofit2 的使用

    本文是 Android RxJava2+Retrofit2+OkHttp3 的使用(一) --基础篇 Retrofit2 的使用 本文的目标是用 Retrofit写一个网络请求: 本文以从获取天气预报 ...

  8. Retrofit2 + OkHttp3设置Http请求头(Headers)方法汇总

    在构建网络层时会遇到一个问题就是要手动配置Http请求的Headers,写入缓存Cookie,自定义的User-Agent等参数,但是对于有几十个接口的网络层,我才不想用注解配置Headers,目前网 ...

  9. Retrofit2和RxJava配合使用Demo

    和Retrofit2单独使用有一些区别 首先,同样写个interface,这里是GitHubService.java,我们这次要实现获取官方提供的测试接口的数据 public interface Gi ...

随机推荐

  1. css+js自动化开发之第十五天

    一.css上一篇的补充 1.position(页面分层) (1)fiexd将标签固定在页面的某个位置 position属性:top,left,right,bottom (2)relative+abso ...

  2. xcode 工具 alcatraz---备用

    简介 Alcatraz 是一个帮你管理 Xcode 插件.模版以及颜色配置的工具.它可以直接集成到 Xcode 的图形界面中,让你感觉就像在使用 Xcode 自带的功能一样. 安装和删除 使用如下的命 ...

  3. WebApp 中用 hashchange 做路由解析

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. matlab取整

    matlab取整 Matlab取整函数有: fix, floor, ceil, round.取整函数在编程时有很大用处.一.取整函数1.向零取整(截尾取整)fix-向零取整(Round towards ...

  5. Struts 2 标签

    注:要使用Strust 2标签需<%@ taglib prefix="s" uri="/struts-tags" %> 表单标签: .form标签 ...

  6. Instant Complexity(模拟,递归)

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1535   Accepted: 529 Description Analyz ...

  7. bzoj3531

    不难想到树链剖分这题的难点是记录的是路径上宗教相同的点裸的想法是对每一种宗教都开一棵线段树,记录每个点的评级但显然这样会爆空间,仔细分析一下,这些线段树内很多点压根就没用到因此我们考虑对线段树动态开点 ...

  8. BZOJ1044: [HAOI2008]木棍分割

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1580  Solved: 567[Submit][Statu ...

  9. 【模拟】Codeforces 691A Fashion in Berland

    题目链接: http://codeforces.com/problemset/problem/691/A 题目大意: n个数0或1,要求恰好n-1个1,如果n为1则那个数一定要是1 题目思路: [模拟 ...

  10. supesite 相关 修改

    1.修改 站点名称及logo http://faq.comsenz.com/viewnews-594 2.supesite 如何 收录论坛 http://faq.comsenz.com/viewnew ...