├── .gitignore ├── Android-Binder机制总结.doc ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── andbase │ │ └── demo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── andbase │ │ │ └── demo │ │ │ ├── Constants.java │ │ │ ├── DownloadManager.java │ │ │ ├── MyApplication.java │ │ │ ├── activity │ │ │ ├── EventActivity.java │ │ │ ├── MainActivity.java │ │ │ └── SecondActivity.java │ │ │ ├── adapter │ │ │ └── DownLoadListAdapter.java │ │ │ ├── base │ │ │ ├── Base.java │ │ │ └── BaseActivity.java │ │ │ ├── bean │ │ │ ├── DownloadInfo.java │ │ │ └── GamesBean.java │ │ │ ├── db │ │ │ ├── DBHelper.java │ │ │ └── DBService.java │ │ │ ├── http │ │ │ ├── HttpBase.java │ │ │ ├── MediaTypeWrap.java │ │ │ ├── OKHttp.java │ │ │ ├── body │ │ │ │ └── FileBody.java │ │ │ ├── cookie │ │ │ │ ├── PersistentCookieStore.java │ │ │ │ └── SerializableHttpCookie.java │ │ │ ├── request │ │ │ │ ├── CountingRequestBody.java │ │ │ │ ├── HttpHeader.java │ │ │ │ ├── HttpMethod.java │ │ │ │ ├── HttpRequest.java │ │ │ │ └── RequestParams.java │ │ │ └── response │ │ │ │ ├── HttpResponse.java │ │ │ │ └── ResponseType.java │ │ │ ├── task │ │ │ └── DownLoadTask.java │ │ │ └── utils │ │ │ ├── DataCleanManager.java │ │ │ ├── HttpSender.java │ │ │ └── Utils.java │ └── res │ │ ├── drawable │ │ └── bg_button.xml │ │ ├── layout │ │ ├── act_event.xml │ │ ├── act_main.xml │ │ ├── act_second.xml │ │ └── item_downloadlist.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── andbase │ └── demo │ └── ExampleUnitTest.java ├── authorInfo.json ├── build.gradle ├── gifs ├── 1449480498_3231.gif ├── 1449567185_3103.jpg ├── 1449628980_4123.gif └── 1449629046_4805.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── build.gradle ├── gradle-jcenter-push.gradle ├── gradle.properties ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ ├── aidl │ │ └── com │ │ │ └── andbase │ │ │ └── tractor │ │ │ └── EventDeliver.aidl │ │ ├── assets │ │ ├── assets │ │ │ └── image │ │ │ │ └── gy_image_close.png │ │ └── image │ │ │ └── gy_image_close.png │ │ └── java │ │ └── com │ │ └── andbase │ │ └── tractor │ │ ├── Constants │ │ └── Constants.java │ │ ├── LittleDialog.java │ │ ├── Tractor.java │ │ ├── event │ │ ├── EventException.java │ │ ├── EventInfo.java │ │ ├── EventTractor.java │ │ ├── EventType.java │ │ ├── PendingPost.java │ │ ├── PostHandler.java │ │ ├── Router.java │ │ ├── Subscribe.java │ │ ├── Subscriber.java │ │ └── services │ │ │ └── TractorService.java │ │ ├── handler │ │ └── LoadHandler.java │ │ ├── listener │ │ ├── LoadListener.java │ │ └── impl │ │ │ └── LoadListenerImpl.java │ │ ├── task │ │ ├── CancelTask.java │ │ ├── Task.java │ │ ├── TaskPool.java │ │ ├── ThreadPool.java │ │ ├── TimeoutCountTask.java │ │ └── threadpool │ │ │ ├── CachedThreadPool.java │ │ │ ├── FixedThreadPool.java │ │ │ ├── ScheduledThreadPool.java │ │ │ └── SingleThreadPool.java │ │ └── utils │ │ ├── BackGroudSeletor.java │ │ ├── DensityUtil.java │ │ ├── HandlerUtils.java │ │ ├── LogUtils.java │ │ └── Util.java └── tuml.puml ├── okhttp ├── .gitignore ├── build.gradle ├── libs │ └── okio.jar └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── okhttp3 │ ├── Address.java │ ├── Authenticator.java │ ├── Cache.java │ ├── CacheControl.java │ ├── Call.java │ ├── Callback.java │ ├── CertificatePinner.java │ ├── Challenge.java │ ├── CipherSuite.java │ ├── Connection.java │ ├── ConnectionPool.java │ ├── ConnectionSpec.java │ ├── Credentials.java │ ├── Dispatcher.java │ ├── Dns.java │ ├── FormBody.java │ ├── Handshake.java │ ├── Headers.java │ ├── HttpUrl.java │ ├── Interceptor.java │ ├── MediaType.java │ ├── MultipartBody.java │ ├── OkHttpClient.java │ ├── Protocol.java │ ├── Request.java │ ├── RequestBody.java │ ├── Response.java │ ├── ResponseBody.java │ ├── Route.java │ ├── TlsVersion.java │ └── internal │ ├── ConnectionSpecSelector.java │ ├── DiskLruCache.java │ ├── FaultHidingSink.java │ ├── Internal.java │ ├── InternalCache.java │ ├── NamedRunnable.java │ ├── OptionalMethod.java │ ├── Platform.java │ ├── RouteDatabase.java │ ├── Util.java │ ├── Version.java │ ├── framed │ ├── ErrorCode.java │ ├── FrameReader.java │ ├── FrameWriter.java │ ├── FramedConnection.java │ ├── FramedStream.java │ ├── Header.java │ ├── HeadersMode.java │ ├── Hpack.java │ ├── Http2.java │ ├── Huffman.java │ ├── NameValueBlockReader.java │ ├── Ping.java │ ├── PushObserver.java │ ├── Settings.java │ ├── Spdy3.java │ └── Variant.java │ ├── http │ ├── AuthenticatorAdapter.java │ ├── CacheRequest.java │ ├── CacheStrategy.java │ ├── HeaderParser.java │ ├── Http1xStream.java │ ├── Http2xStream.java │ ├── HttpDate.java │ ├── HttpEngine.java │ ├── HttpMethod.java │ ├── HttpStream.java │ ├── OkHeaders.java │ ├── RealResponseBody.java │ ├── RequestException.java │ ├── RequestLine.java │ ├── RetryableSink.java │ ├── RouteException.java │ ├── RouteSelector.java │ ├── StatusLine.java │ └── StreamAllocation.java │ ├── io │ ├── FileSystem.java │ └── RealConnection.java │ └── tls │ ├── DistinguishedNameParser.java │ └── OkHostnameVerifier.java ├── okio ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── okio │ ├── AsyncTimeout.java │ ├── Base64.java │ ├── Buffer.java │ ├── BufferedSink.java │ ├── BufferedSource.java │ ├── ByteString.java │ ├── DeflaterSink.java │ ├── ForwardingSink.java │ ├── ForwardingSource.java │ ├── ForwardingTimeout.java │ ├── GzipSink.java │ ├── GzipSource.java │ ├── InflaterSource.java │ ├── Okio.java │ ├── RealBufferedSink.java │ ├── RealBufferedSource.java │ ├── Segment.java │ ├── SegmentPool.java │ ├── SegmentedByteString.java │ ├── Sink.java │ ├── Source.java │ ├── Timeout.java │ └── Util.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | .idea/ 4 | .DS_Store 5 | /build 6 | /captures 7 | *.iml 8 | -------------------------------------------------------------------------------- /Android-Binder机制总结.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huxq17/tractor/7e3023f21f2b73193249947e34d49a4ef102152d/Android-Binder机制总结.doc -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.andbase.demo" 9 | minSdkVersion 10 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | // dexOptions { 21 | // jumboMode = true 22 | // javaMaxHeapSize "4g" 23 | // } 24 | lintOptions { 25 | abortOnError false 26 | } 27 | } 28 | 29 | dependencies { 30 | compile fileTree(include: ['*.jar'], dir: 'libs') 31 | testCompile 'junit:junit:4.12' 32 | // compile project(':library') 33 | compile 'com.huxq17.android:tractor:1.3.1' 34 | compile project(':okhttp') 35 | // compile 'com.squareup.okhttp:okhttp:2.7.0' 36 | compile 'com.android.support:appcompat-v7:23.1.0' 37 | compile 'com.huxq17.xrefreshview:xrefreshview:2.1.1' 38 | compile 'com.android.support:recyclerview-v7:23.1.1' 39 | 40 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\develop\tools\adt-bundle-windows-x86_64-20140702\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/andbase/demo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/Constants.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo; 2 | 3 | /** 4 | * Created by huxq17 on 2016/11/16. 5 | */ 6 | 7 | public class Constants { 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/DownloadManager.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo; 2 | 3 | /** 4 | * Created by huxq17 on 2016/3/30. 5 | */ 6 | public class DownloadManager { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo; 2 | 3 | import android.app.Application; 4 | 5 | import com.andbase.tractor.Tractor; 6 | 7 | /** 8 | * Created by 2144 on 2016/12/21. 9 | */ 10 | 11 | public class MyApplication extends Application { 12 | @Override 13 | public void onCreate() { 14 | super.onCreate(); 15 | Tractor.init(getApplicationContext()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/activity/EventActivity.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.activity; 2 | 3 | import android.os.Bundle; 4 | 5 | import com.andbase.demo.R; 6 | import com.andbase.demo.base.BaseActivity; 7 | import com.andbase.tractor.Tractor; 8 | import com.andbase.tractor.event.Subscribe; 9 | import com.andbase.tractor.event.Subscriber; 10 | import com.andbase.tractor.task.Task; 11 | import com.andbase.tractor.task.TaskPool; 12 | import com.andbase.tractor.utils.LogUtils; 13 | 14 | /** 15 | * Created by huxq17 on 2016/3/30. 16 | */ 17 | public class EventActivity extends BaseActivity { 18 | private Subscriber subscriber1 = new Subscriber() { 19 | @Override 20 | @Subscribe(mainThread = true, sticky = false) 21 | public void onEvent(String event) { 22 | toast("subscriber1 value = " + event); 23 | LogUtils.d("subscriber1 value = " + event); 24 | } 25 | }; 26 | private Subscriber subscriber2 = new Subscriber(1) { 27 | @Override 28 | @Subscribe(mainThread = true, sticky = false) 29 | public void onEvent(String event) { 30 | toast("subscriber2 value = " + event); 31 | LogUtils.d("subscriber2 value = " + event); 32 | } 33 | }; 34 | 35 | @Override 36 | public void onUserInteraction() { 37 | super.onUserInteraction(); 38 | LogUtils.e("Tractor.removeStickyEvent(new Integer(1234)) result=" + Tractor.removeStickyEvent(new Integer(1234))); 39 | } 40 | 41 | @Override 42 | protected void onCreate(Bundle savedInstanceState) { 43 | super.onCreate(savedInstanceState); 44 | setContentView(R.layout.act_event); 45 | initView(); 46 | Tractor.register(subscriber1); 47 | Tractor.register(subscriber2); 48 | Tractor.register(new Subscriber(1245) { 49 | @Override 50 | public void onEvent(Integer event) { 51 | toast("stickyevent event=" + event); 52 | LogUtils.e("stickyevent event=" + event); 53 | } 54 | }); 55 | post(); 56 | } 57 | 58 | private void post() { 59 | Tractor.post("来自主线程"); 60 | Tractor.post(1, "来自主线程2"); 61 | TaskPool.getInstance().execute(new Task() { 62 | @Override 63 | public void onRun() { 64 | //在非主线程发消息 65 | Tractor.post("来自非主线程"); 66 | Tractor.post(1, "来自非主线程2"); 67 | } 68 | 69 | @Override 70 | public void cancelTask() { 71 | } 72 | }); 73 | } 74 | 75 | @Override 76 | protected void onDestroy() { 77 | super.onDestroy(); 78 | Tractor.unregister(subscriber1); 79 | Tractor.unregister(1); 80 | post(); 81 | } 82 | 83 | private void initView() { 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/activity/SecondActivity.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.activity; 2 | 3 | import android.os.Bundle; 4 | import android.os.Handler; 5 | import android.support.v7.widget.LinearLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | 8 | import com.andbase.demo.R; 9 | import com.andbase.demo.adapter.DownLoadListAdapter; 10 | import com.andbase.demo.base.BaseActivity; 11 | import com.andbase.demo.bean.GamesBean; 12 | import com.andbase.tractor.Tractor; 13 | import com.andbase.tractor.event.Subscribe; 14 | import com.andbase.tractor.event.Subscriber; 15 | import com.andbase.tractor.task.Task; 16 | import com.andbase.tractor.task.TaskPool; 17 | import com.andbase.tractor.utils.LogUtils; 18 | import com.andview.refreshview.XRefreshView; 19 | 20 | import java.util.List; 21 | 22 | /** 23 | * Created by huxq17 on 2016/3/30. 24 | */ 25 | public class SecondActivity extends BaseActivity { 26 | private com.andview.refreshview.XRefreshView xRefreshView; 27 | private RecyclerView mRecyclerView; 28 | private DownLoadListAdapter adapter; 29 | private List list; 30 | private Subscriber subscriber1 = new Subscriber() { 31 | @Override 32 | @Subscribe(mainThread = true, sticky = false) 33 | public void onEvent(String event) { 34 | toast("subscriber1 value = " + event); 35 | LogUtils.d("subscriber1 value = " + event); 36 | } 37 | }; 38 | private Subscriber subscriber2 = new Subscriber(1) { 39 | @Override 40 | @Subscribe(mainThread = true, sticky = false) 41 | public void onEvent(String event) { 42 | toast("subscriber2 value = " + event); 43 | LogUtils.d("subscriber2 value = " + event); 44 | } 45 | }; 46 | 47 | @Override 48 | public void onUserInteraction() { 49 | super.onUserInteraction(); 50 | LogUtils.e("Tractor.removeStickyEvent(new Integer(1234)) result="+Tractor.removeStickyEvent(new Integer(1234))); 51 | } 52 | 53 | @Override 54 | protected void onCreate(Bundle savedInstanceState) { 55 | super.onCreate(savedInstanceState); 56 | setContentView(R.layout.act_second); 57 | initView(); 58 | xRefreshView.setXRefreshViewListener(new XRefreshView.SimpleXRefreshListener() { 59 | @Override 60 | public void onRefresh() { 61 | super.onRefresh(); 62 | new Handler().postDelayed(new Runnable() { 63 | @Override 64 | public void run() { 65 | xRefreshView.stopRefresh(); 66 | } 67 | }, 2000); 68 | } 69 | }); 70 | Tractor.register(subscriber1); 71 | Tractor.register(subscriber2); 72 | Tractor.register(new Subscriber(1245) { 73 | @Override 74 | public void onEvent(Integer event) { 75 | toast("stickyevent event=" + event); 76 | LogUtils.e("stickyevent event=" + event); 77 | } 78 | }); 79 | post(); 80 | } 81 | 82 | private void post() { 83 | Tractor.post("来自主线程"); 84 | Tractor.post(1, "来自主线程2"); 85 | TaskPool.getInstance().execute(new Task() { 86 | @Override 87 | public void onRun() { 88 | //在非主线程发消息 89 | Tractor.post("来自非主线程"); 90 | Tractor.post(1, "来自非主线程2"); 91 | } 92 | 93 | @Override 94 | public void cancelTask() { 95 | } 96 | }); 97 | } 98 | 99 | @Override 100 | protected void onDestroy() { 101 | super.onDestroy(); 102 | Tractor.unregister(subscriber1); 103 | Tractor.unregister(1); 104 | post(); 105 | } 106 | 107 | private void initView() { 108 | xRefreshView = (XRefreshView) findViewById(R.id.xrefreshview); 109 | mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); 110 | adapter = new DownLoadListAdapter(this, list); 111 | mRecyclerView.setHasFixedSize(true); 112 | mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 113 | mRecyclerView.setAdapter(adapter); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/adapter/DownLoadListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.Button; 9 | import android.widget.ProgressBar; 10 | import android.widget.TextView; 11 | 12 | import com.andbase.demo.R; 13 | import com.andbase.demo.bean.GamesBean; 14 | import com.andview.refreshview.recyclerview.BaseRecyclerAdapter; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | /** 20 | * Created by 2144 on 2016/3/30. 21 | */ 22 | public class DownLoadListAdapter extends BaseRecyclerAdapter { 23 | private List mList = new ArrayList<>(); 24 | private Context mContext; 25 | 26 | public DownLoadListAdapter(Context context, List list) { 27 | if (list != null) { 28 | mList = list; 29 | } 30 | mContext = context; 31 | } 32 | 33 | public void setData(List list) { 34 | if (list != null) { 35 | mList = list; 36 | } 37 | } 38 | 39 | @Override 40 | public ListHolder getViewHolder(View view) { 41 | return new ListHolder(view, false); 42 | } 43 | 44 | @Override 45 | public ListHolder onCreateViewHolder(ViewGroup parent, int viewType, boolean isItem) { 46 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_downloadlist, parent, false); 47 | ListHolder listHolder = new ListHolder(view, true); 48 | return listHolder; 49 | } 50 | 51 | @Override 52 | public void onBindViewHolder(ListHolder holder, int position, boolean isItem) { 53 | GamesBean gamesBean = mList.get(position); 54 | if (gamesBean != null) { 55 | holder.pbProcess.setProgress(gamesBean.progress); 56 | holder.tvName.setText(gamesBean.name); 57 | holder.tvSpeed.setText(gamesBean.speed); 58 | holder.tvDownSize.setText(gamesBean.downloadSize); 59 | holder.btInstall.setOnClickListener(new View.OnClickListener() { 60 | @Override 61 | public void onClick(View v) { 62 | 63 | } 64 | }); 65 | } 66 | } 67 | 68 | @Override 69 | public int getAdapterItemCount() { 70 | return mList.size(); 71 | } 72 | 73 | public class ListHolder extends RecyclerView.ViewHolder { 74 | public Button btInstall; 75 | public TextView tvName, tvDownSize, tvSpeed; 76 | public ProgressBar pbProcess; 77 | 78 | public ListHolder(View itemView, boolean isItem) { 79 | super(itemView); 80 | if (isItem) { 81 | btInstall = (Button) itemView.findViewById(R.id.bt_install); 82 | tvName = (TextView) itemView.findViewById(R.id.tv_name); 83 | tvDownSize = (TextView) itemView.findViewById(R.id.tv_downsize); 84 | tvSpeed = (TextView) itemView.findViewById(R.id.tv_downspeed); 85 | pbProcess = (ProgressBar) itemView.findViewById(R.id.pb_process); 86 | } 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/base/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.base; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | 6 | import com.andbase.tractor.task.TaskPool; 7 | 8 | public class BaseActivity extends Activity { 9 | 10 | private Base mBase; 11 | 12 | @Override 13 | protected void attachBaseContext(Context newBase) { 14 | super.attachBaseContext(newBase); 15 | mBase = Base.getInstance(getApplicationContext()); 16 | } 17 | 18 | /** 19 | * 格式化字符串 20 | * 21 | * @param format 22 | * @param args 23 | */ 24 | public String format(String format, Object... args) { 25 | if (mBase != null) { 26 | return mBase.format(format, args); 27 | } else { 28 | return null; 29 | } 30 | } 31 | 32 | public void setText(Object obj, String str) { 33 | if (mBase != null) { 34 | mBase.setText(obj, str); 35 | } 36 | } 37 | 38 | /** 39 | * 获取edittext,textView,checkbox和button的文字 40 | * 41 | * @param obj 42 | * @return 43 | */ 44 | public String getText(Object obj) { 45 | if (mBase != null) { 46 | return mBase.getText(obj); 47 | } else { 48 | return ""; 49 | } 50 | } 51 | 52 | public boolean isEmpty(Object obj) { 53 | if (mBase != null) { 54 | return mBase.isEmpty(obj); 55 | } else { 56 | return true; 57 | } 58 | } 59 | 60 | public boolean isEmpty(String str) { 61 | return mBase != null ? mBase.isEmpty(str) : true; 62 | } 63 | 64 | public void toast(String msg) { 65 | if (mBase != null) { 66 | mBase.toast(msg); 67 | } 68 | } 69 | 70 | public void toastAll(String msg) { 71 | if (mBase != null) { 72 | toastAll(msg); 73 | } 74 | } 75 | 76 | public void toastL(String msg) { 77 | if (mBase != null) { 78 | mBase.toastL(msg); 79 | } 80 | } 81 | 82 | public void toastAllL(String msg) { 83 | if (mBase != null) { 84 | mBase.toastAllL(msg); 85 | } 86 | } 87 | 88 | @Override 89 | protected void onDestroy() { 90 | super.onDestroy(); 91 | //当activity或者fragment销毁了,最好取消这个页面上的请求,防止一些异常 92 | TaskPool.getInstance().cancelTask(this); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/bean/DownloadInfo.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.bean; 2 | 3 | import com.andbase.tractor.task.Task; 4 | import com.andbase.tractor.utils.LogUtils; 5 | 6 | /** 7 | * 记载下载器详细信息的类 8 | */ 9 | public class DownloadInfo { 10 | public int downloadId;//下载器id 11 | public long startPos = -1;//开始点 12 | public long endPos = -1;//结束点 13 | public long completeSize;//完成度 14 | public String url;//下载器网络标识 15 | public long fileLength; 16 | public String filePath;//文件保存路径 17 | public String fileDir;//保存文件的文件夹路径 18 | public String filename;//保存的文件名 19 | public String tempFileName; 20 | public String tempFilePath; 21 | public int threadNum; 22 | private int process; 23 | 24 | public DownloadInfo(String url, String fileDir, String filename, int threadNum) { 25 | this.url = url; 26 | this.fileDir = fileDir; 27 | this.filename = filename; 28 | this.filePath = this.fileDir + this.filename; 29 | this.threadNum = threadNum; 30 | this.tempFileName = filename + ".temp"; 31 | this.tempFilePath = this.fileDir + this.tempFileName; 32 | } 33 | 34 | public DownloadInfo(int downloadId, 35 | long startPosition, long endPosition, String url) { 36 | this.downloadId = downloadId; 37 | this.startPos = startPosition; 38 | this.endPos = endPosition; 39 | this.url = url; 40 | } 41 | 42 | /** 43 | * 计算进度,并通知ui更新 44 | * 45 | * @param done 46 | */ 47 | public boolean compute(Task task, long done) { 48 | // LogUtils.d("completeSize=" + completeSize + ";done=" + done+";task.isRunning="+task.isRunning()); 49 | if (task == null || !task.isRunning()) { 50 | //当下载任务不在运行时,返回false,主要用于其他下载子线程停止下载动作 51 | return false; 52 | } 53 | completeSize += done; 54 | int process = (int) (100 * (1.0f * completeSize / fileLength)); 55 | if (process != this.process) { 56 | this.process = process; 57 | task.notifyLoading(this.process); 58 | } 59 | // if (hasDownloadSuccess()) { 60 | //// synchronized (task) { 61 | // task.notify(); 62 | //// } 63 | // } 64 | return true; 65 | } 66 | 67 | public boolean hasDownloadSuccess() { 68 | LogUtils.d("hasDownloadSuccess completeSize=" + completeSize + ";fileLength=" + fileLength); 69 | return completeSize >= fileLength; 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return "DownloadInfo{" + 75 | "startPos=" + startPos + 76 | ", endPos=" + endPos + 77 | ", compeleteSize=" + completeSize + 78 | ", url='" + url + '\'' + 79 | ", fileLength=" + fileLength + 80 | ", filePath='" + filePath + '\'' + 81 | ", fileDir='" + fileDir + '\'' + 82 | ", filename='" + filename + '\'' + 83 | ", threadNum=" + threadNum + 84 | '}'; 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/bean/GamesBean.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.bean; 2 | 3 | /** 4 | * Created by huxq17 on 2016/3/30. 5 | */ 6 | public class GamesBean { 7 | public String name; 8 | public String downloadSize; 9 | public String speed; 10 | public int progress; 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/db/DBHelper.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.db; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | public class DBHelper extends SQLiteOpenHelper { 8 | // download.db-->数据库名 9 | public DBHelper(Context context) { 10 | super(context, "download.db", null, 1); 11 | } 12 | 13 | /** 14 | * 在download.db数据库下创建一个download_info表存储下载信息 15 | */ 16 | @Override 17 | public void onCreate(SQLiteDatabase db) { 18 | db.execSQL("create table download_info(thread_id integer, " 19 | + "startposition integer,endposition integer,url char," + 20 | "primary key(thread_id,url))"); 21 | } 22 | 23 | @Override 24 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 25 | db.execSQL("DROP TABLE IF EXISTS download_info"); 26 | onCreate(db); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/db/DBService.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.db; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | import android.util.Log; 8 | 9 | import com.andbase.demo.bean.DownloadInfo; 10 | import com.andbase.tractor.utils.LogUtils; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | public class DBService { 16 | private DBHelper dbHelper; 17 | private static DBService instance; 18 | private static final String DOWNLOAD_TABLE = "download_info"; 19 | 20 | private DBService(Context context) { 21 | dbHelper = new DBHelper(context); 22 | } 23 | 24 | /** 25 | * @param context 26 | * @return 27 | */ 28 | public static DBService getInstance(Context context) { 29 | if (context == null) { 30 | throw new RuntimeException("context == null"); 31 | } 32 | if (!(context instanceof Application)) { 33 | context = context.getApplicationContext(); 34 | } 35 | if (instance == null) { 36 | synchronized (DBService.class) { 37 | if (instance == null) { 38 | instance = new DBService(context); 39 | return instance; 40 | } 41 | } 42 | } 43 | return instance; 44 | } 45 | 46 | /** 47 | * 得到下载具体信息 48 | */ 49 | public synchronized List getInfos(String urlstr) { 50 | List list = new ArrayList(); 51 | SQLiteDatabase database = dbHelper.getReadableDatabase(); 52 | String sql = "select thread_id,startposition,endposition,url from "+DOWNLOAD_TABLE+" where url=?"; 53 | Cursor cursor = database.rawQuery(sql, new String[]{urlstr}); 54 | while (cursor.moveToNext()) { 55 | DownloadInfo info = new DownloadInfo(cursor.getInt(0), cursor.getInt(1), cursor.getLong(2), 56 | cursor.getString(3)); 57 | list.add(info); 58 | } 59 | cursor.close(); 60 | database.close(); 61 | return list; 62 | } 63 | 64 | 65 | /** 66 | * 更新数据库中的下载信息 67 | */ 68 | public synchronized void updataInfos(int threadId, long startposition, long endposition, String url) { 69 | long totalCount = getCount(DOWNLOAD_TABLE); 70 | SQLiteDatabase database = dbHelper.getReadableDatabase(); 71 | // 如果存在就更新,不存在就插入 72 | String sql = "replace into " + DOWNLOAD_TABLE + "(thread_id,startposition,endposition,url) values(?,?,?,?)"; 73 | Object[] bindArgs = {threadId, startposition, endposition, url}; 74 | database.execSQL(sql, bindArgs); 75 | database.close(); 76 | LogUtils.i("updataInfos total=" + totalCount + ";threadid=" + threadId + ";startposition=" + startposition + ";endposition=" + endposition); 77 | } 78 | 79 | /** 80 | * 关闭数据库 81 | */ 82 | public void closeDb() { 83 | dbHelper.close(); 84 | } 85 | 86 | /** 87 | * 下载完成后删除数据库中的数据 88 | */ 89 | public synchronized void delete(String url) { 90 | long totalCount = getCount(DOWNLOAD_TABLE); 91 | SQLiteDatabase database = dbHelper.getReadableDatabase(); 92 | int count = database.delete(DOWNLOAD_TABLE, "url=?", new String[]{url}); 93 | // Log.i("delete", "delete total=" + totalCount + ";delete count=" + count + ";url=" + url); 94 | database.close(); 95 | } 96 | 97 | private long getCount(String table) { 98 | SQLiteDatabase database = dbHelper.getReadableDatabase(); 99 | Cursor cursor = database.rawQuery("select count(*)from " + table, null); 100 | cursor.moveToFirst(); 101 | long result = cursor.getLong(0); 102 | cursor.close(); 103 | database.close(); 104 | return result; 105 | } 106 | 107 | public void saveOrUpdateInfos() { 108 | 109 | } 110 | 111 | public synchronized void deleteByIdAndUrl(int id, String url) { 112 | SQLiteDatabase database = dbHelper.getReadableDatabase(); 113 | int count = database.delete(DOWNLOAD_TABLE, "thread_id=? and url=?", new String[]{ 114 | id + "", url}); 115 | Log.i("delete", "delete id=" + id + "," + "count=" + count); 116 | database.close(); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/HttpBase.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http; 2 | 3 | import com.andbase.demo.http.request.HttpRequest; 4 | import com.andbase.demo.http.response.HttpResponse; 5 | import com.andbase.tractor.listener.LoadListener; 6 | 7 | /** 8 | * http请求的基类 9 | */ 10 | public interface HttpBase { 11 | /** 12 | * get请求 13 | * 14 | * @param request http请求 15 | * @param listener 监听 同步请求的时候这个参数是用不到的,同步请求可以传null 16 | * @param tag 17 | * @return 封装了网络请求的响应 同步请求的时候返回值不为null,异步请求的时候总是null 18 | */ 19 | public HttpResponse get(HttpRequest request, LoadListener listener, Object... tag); 20 | 21 | /** 22 | * post请求 23 | * 24 | * @param request http请求 25 | * @param listener 监听 同步请求的时候这个参数是用不到的,同步请求可以传null 26 | * @param tag 27 | * @return 封装了网络请求的响应 同步请求的时候返回值不为null,异步请求的时候总是null 28 | */ 29 | public HttpResponse post(HttpRequest request, LoadListener listener, Object... tag); 30 | 31 | /** 32 | * get post以外的其他请求 33 | * 34 | * @param request http请求 35 | * @param listener 监听 同步请求的时候这个参数是用不到的,同步请求可以传null 36 | * @param tag 37 | * @return 封装了网络请求的响应 同步请求的时候返回值不为null,异步请求的时候总是null 38 | */ 39 | public HttpResponse request(HttpRequest request, LoadListener listener, Object... tag); 40 | 41 | /** 42 | * 取消特定tag的http请求 43 | * @param tag 44 | */ 45 | public void cancel(Object... tag); 46 | } -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/MediaTypeWrap.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http; 2 | 3 | 4 | import okhttp3.MediaType; 5 | 6 | /** 7 | * 进行post请求时 8 | * @author huxq17 9 | * 10 | */ 11 | public class MediaTypeWrap { 12 | /** 13 | * form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式) 14 | */ 15 | public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType 16 | .parse("application/x-www-form-urlencoded; charset=utf-8"); 17 | /** 18 | * 二进制流数据(如常见的文件下载) 19 | */ 20 | public static final MediaType MEDIA_TYPE_DOWNLOAD = MediaType 21 | .parse("application/octet-stream; charset=utf-8"); 22 | /** 23 | * JSON数据格式 24 | */ 25 | public static final MediaType MEDIA_TYPE_JSON = MediaType 26 | .parse("application/json; charset=utf-8"); 27 | /** 28 | * 纯文本格式 29 | */ 30 | public static final MediaType MEDIA_TYPE_TEXT = MediaType 31 | .parse("text/plain; charset=utf-8"); 32 | /** 33 | * 表单中进行文件上传 34 | */ 35 | public static final MediaType MEDIA_TYPE_UPLOAD = MediaType 36 | .parse("multipart/form-data; charset=utf-8"); 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/body/FileBody.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http.body; 2 | 3 | import java.io.File; 4 | import java.net.FileNameMap; 5 | import java.net.URLConnection; 6 | 7 | /** 8 | * Created by huxq17 on 2015/11/26. 9 | */ 10 | public class FileBody { 11 | /* 上传文件的数据 */ 12 | private byte[] data; 13 | private File file; 14 | /* 文件路径 */ 15 | private String filePath; 16 | /* 请求参数名称*/ 17 | private String parameterName; 18 | /* 内容类型 */ 19 | private String contentType = "application/octet-stream"; 20 | 21 | public FileBody(String parameterName, byte[] data, String filePath, String contentType) { 22 | this.data = data; 23 | this.filePath = filePath; 24 | this.parameterName = parameterName; 25 | if (contentType != null) { 26 | this.contentType = contentType; 27 | } else { 28 | this.contentType = getContentType(filePath); 29 | } 30 | } 31 | 32 | private String getContentType(String path) { 33 | FileNameMap fileNameMap = URLConnection.getFileNameMap(); 34 | String contentType = fileNameMap.getContentTypeFor(path); 35 | if (contentType == null) { 36 | contentType = "application/octet-stream"; 37 | } 38 | return contentType; 39 | } 40 | 41 | public FileBody(String parameterName, String filePath, File file) { 42 | this(parameterName,filePath,file,null); 43 | } 44 | 45 | public FileBody(String parameterName, String filePath, File file, String contentType) { 46 | this.filePath = filePath; 47 | this.parameterName = parameterName; 48 | this.file = file; 49 | if (contentType != null) { 50 | this.contentType = contentType; 51 | } else { 52 | this.contentType = getContentType(filePath); 53 | } 54 | } 55 | 56 | public File getFile() { 57 | return file; 58 | } 59 | 60 | public byte[] getData() { 61 | return data; 62 | } 63 | 64 | public String getFilPath() { 65 | return filePath; 66 | } 67 | 68 | public void setFilePath(String filePath) { 69 | this.filePath = filePath; 70 | } 71 | 72 | public String getParameterName() { 73 | return parameterName; 74 | } 75 | 76 | public void setParameterName(String parameterName) { 77 | this.parameterName = parameterName; 78 | } 79 | 80 | public String getContentType() { 81 | return contentType; 82 | } 83 | 84 | public void setContentType(String contentType) { 85 | this.contentType = contentType; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/cookie/SerializableHttpCookie.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http.cookie; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | 6 | import java.io.IOException; 7 | import java.io.ObjectInputStream; 8 | import java.io.ObjectOutputStream; 9 | import java.io.Serializable; 10 | import java.net.HttpCookie; 11 | 12 | /** 13 | * Created by jiechic on 15/5/27. 14 | */ 15 | @TargetApi(Build.VERSION_CODES.GINGERBREAD) 16 | public class SerializableHttpCookie implements Serializable { 17 | private static final long serialVersionUID = 6374381323722046732L; 18 | 19 | private transient final HttpCookie cookie; 20 | private transient HttpCookie clientCookie; 21 | 22 | public SerializableHttpCookie(HttpCookie cookie) { 23 | this.cookie = cookie; 24 | } 25 | 26 | public HttpCookie getCookie() { 27 | HttpCookie bestCookie = cookie; 28 | if (clientCookie != null) { 29 | bestCookie = clientCookie; 30 | } 31 | return bestCookie; 32 | } 33 | 34 | private void writeObject(ObjectOutputStream out) throws IOException { 35 | out.writeObject(cookie.getName()); 36 | out.writeObject(cookie.getValue()); 37 | out.writeObject(cookie.getComment()); 38 | out.writeObject(cookie.getCommentURL()); 39 | out.writeObject(cookie.getDomain()); 40 | out.writeLong(cookie.getMaxAge()); 41 | out.writeObject(cookie.getPath()); 42 | out.writeObject(cookie.getPortlist()); 43 | out.writeInt(cookie.getVersion()); 44 | out.writeBoolean(cookie.getSecure()); 45 | out.writeBoolean(cookie.getDiscard()); 46 | } 47 | 48 | private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 49 | String name = (String) in.readObject(); 50 | String value = (String) in.readObject(); 51 | clientCookie = new HttpCookie(name, value); 52 | clientCookie.setComment((String) in.readObject()); 53 | clientCookie.setCommentURL((String) in.readObject()); 54 | clientCookie.setDomain((String) in.readObject()); 55 | clientCookie.setMaxAge(in.readLong()); 56 | clientCookie.setPath((String) in.readObject()); 57 | clientCookie.setPortlist((String) in.readObject()); 58 | clientCookie.setVersion(in.readInt()); 59 | clientCookie.setSecure(in.readBoolean()); 60 | clientCookie.setDiscard(in.readBoolean()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/request/CountingRequestBody.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http.request; 2 | 3 | import com.andbase.tractor.task.Task; 4 | 5 | import java.io.IOException; 6 | 7 | import okhttp3.MediaType; 8 | import okhttp3.RequestBody; 9 | import okio.Buffer; 10 | import okio.BufferedSink; 11 | import okio.ForwardingSink; 12 | import okio.Okio; 13 | import okio.Sink; 14 | 15 | /** 16 | * Decorates an OkHttp request body to count the number of bytes written when writing it. Can 17 | * decorate any request body, but is most useful for tracking the upload progress of large 18 | * multipart requests. 19 | * 20 | * @author Leo Nikkil 21 | */ 22 | public class CountingRequestBody extends RequestBody { 23 | 24 | protected RequestBody delegate; 25 | protected Task mTask; 26 | private int mProcess = -1; 27 | 28 | protected CountingSink countingSink; 29 | 30 | public CountingRequestBody(RequestBody delegate, Task task) { 31 | this.delegate = delegate; 32 | this.mTask = task; 33 | } 34 | 35 | @Override 36 | public MediaType contentType() { 37 | return delegate.contentType(); 38 | } 39 | 40 | @Override 41 | public long contentLength() { 42 | try { 43 | return delegate.contentLength(); 44 | } catch (IOException e) { 45 | e.printStackTrace(); 46 | } 47 | return -1; 48 | } 49 | 50 | @Override 51 | public void writeTo(BufferedSink sink) throws IOException { 52 | BufferedSink bufferedSink; 53 | 54 | countingSink = new CountingSink(sink); 55 | bufferedSink = Okio.buffer(countingSink); 56 | 57 | delegate.writeTo(bufferedSink); 58 | 59 | bufferedSink.flush(); 60 | } 61 | 62 | protected final class CountingSink extends ForwardingSink { 63 | 64 | private long bytesWritten = 0; 65 | 66 | public CountingSink(Sink delegate) { 67 | super(delegate); 68 | } 69 | 70 | @Override 71 | public void write(Buffer source, long byteCount) throws IOException { 72 | super.write(source, byteCount); 73 | 74 | bytesWritten += byteCount; 75 | int process = (int) (1.0 * bytesWritten / contentLength() * 100); 76 | if (mTask != null&&process!=mProcess) { 77 | mTask.notifyLoading(process); 78 | mProcess = process; 79 | } 80 | if (process == 100) { 81 | mTask = null; 82 | } 83 | } 84 | 85 | } 86 | } -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/request/HttpHeader.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http.request; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedHashMap; 5 | 6 | public final class HttpHeader { 7 | private HashMap mHeader; 8 | 9 | public HttpHeader() { 10 | mHeader = new HashMap<>(); 11 | } 12 | /** 13 | * Adds a header with {@code name} and {@code value}. Prefer this method for 14 | * multiply-valued headers like "Cookie". 15 | */ 16 | public void addHeader(String name,String value){ 17 | mHeader.put(name,value); 18 | } 19 | public void setHeader(LinkedHashMap header){ 20 | this.mHeader = header; 21 | } 22 | 23 | public void removeHeader(String name){ 24 | mHeader.remove(name); 25 | } 26 | public HashMap getHeaders(){ 27 | return mHeader; 28 | } 29 | public void clear(){ 30 | mHeader.clear(); 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/request/HttpMethod.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http.request; 2 | 3 | /** 4 | * Created by huxq17 on 2015/11/26. 5 | */ 6 | public enum HttpMethod { 7 | GET("GET"), 8 | POST("POST"), 9 | PUT("PUT"), 10 | PATCH("PATCH"), 11 | HEAD("HEAD"), 12 | MOVE("MOVE"), 13 | COPY("COPY"), 14 | DELETE("DELETE"), 15 | OPTIONS("OPTIONS"), 16 | TRACE("TRACE"), 17 | CONNECT("CONNECT"); 18 | 19 | private final String value; 20 | 21 | HttpMethod(String value) { 22 | this.value = value; 23 | } 24 | 25 | public static boolean permitsRetry(HttpMethod method) { 26 | return method == GET; 27 | } 28 | 29 | public static boolean permitsCache(HttpMethod method) { 30 | return method == GET || method == POST; 31 | } 32 | 33 | public static boolean requiresRequestBody(HttpMethod method) { 34 | return method == POST 35 | || method == PUT 36 | || method == PATCH; 37 | } 38 | 39 | public static boolean permitsRequestBody(HttpMethod method) { 40 | return requiresRequestBody(method) 41 | || method==OPTIONS 42 | || method == DELETE; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return this.value; 48 | } 49 | } -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/request/RequestParams.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http.request; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.andbase.demo.http.body.FileBody; 6 | import com.andbase.tractor.utils.LogUtils; 7 | 8 | import java.io.File; 9 | import java.util.ArrayList; 10 | import java.util.LinkedHashMap; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by 2144 on 2015/11/26. 15 | */ 16 | public class RequestParams { 17 | private String contentType = "application/x-www-form-urlencoded"; 18 | private String charSet = "utf-8"; 19 | private String stringParams; 20 | 21 | private LinkedHashMap mParams; 22 | private List mFiles; 23 | 24 | public RequestParams() { 25 | mParams = new LinkedHashMap<>(); 26 | mFiles = new ArrayList<>(); 27 | } 28 | 29 | public boolean isEmpty() { 30 | return TextUtils.isEmpty(stringParams) && 31 | (mParams == null || mParams != null && mParams.size() == 0) && (mFiles == null || mFiles != null && mFiles.size() == 0); 32 | } 33 | 34 | /** 35 | * 提交普通参数 36 | * 37 | * @param name 38 | * @param params 39 | */ 40 | public void addParams(String name, Object params) { 41 | mParams.put(name, params); 42 | } 43 | 44 | public void setParams(LinkedHashMap params) { 45 | mParams = params; 46 | } 47 | 48 | public String getStringParams() { 49 | return stringParams; 50 | } 51 | 52 | public void setStringParams(String stringParams) { 53 | this.stringParams = stringParams; 54 | } 55 | 56 | /** 57 | * 提交文件 58 | * 59 | * @param file 60 | */ 61 | public void addFile(File file) { 62 | if (file == null || !file.exists()) { 63 | throw new RuntimeException("file==null||!file.exists()"); 64 | } 65 | FileBody body = new FileBody(file.getName(), file.getAbsolutePath(), file); 66 | mFiles.add(body); 67 | } 68 | 69 | /** 70 | * 提交文件 71 | * 72 | * @param name 73 | */ 74 | public void addFile(String name, File file) { 75 | if (file == null || !file.exists()) { 76 | throw new RuntimeException("file==null||!file.exists()"); 77 | } 78 | FileBody body = new FileBody(name, file.getAbsolutePath(), file); 79 | mFiles.add(body); 80 | } 81 | 82 | /** 83 | * 提交文件 84 | * 85 | * @param name 86 | */ 87 | public void addFile(String name, File file, String contentType) { 88 | if (file == null || !file.exists()) { 89 | throw new RuntimeException("file==null||!file.exists()"); 90 | } 91 | FileBody body = new FileBody(name, file.getAbsolutePath(), file, contentType); 92 | mFiles.add(body); 93 | } 94 | 95 | public void clear() { 96 | mParams.clear(); 97 | mFiles.clear(); 98 | } 99 | 100 | public LinkedHashMap getmParams() { 101 | return mParams; 102 | } 103 | 104 | public List getFiles() { 105 | return mFiles; 106 | } 107 | 108 | public void setContentType(String contentType) { 109 | this.contentType = contentType; 110 | } 111 | 112 | public void setCharSet(String charSet) { 113 | this.charSet = charSet; 114 | } 115 | 116 | public String getContentType() { 117 | return contentType; 118 | } 119 | 120 | public String getCharSet() { 121 | return charSet; 122 | } 123 | 124 | @Override 125 | public String toString() { 126 | if (!TextUtils.isEmpty(stringParams)) { 127 | return stringParams; 128 | } 129 | StringBuilder sb = new StringBuilder(); 130 | for (LinkedHashMap.Entry set :mParams.entrySet()) { 131 | if (sb.length() > 0) { 132 | sb.append("&"); 133 | } 134 | sb.append(set.getKey()).append("=").append(set.getValue()); 135 | } 136 | LogUtils.d("http params=" + sb.toString()); 137 | return sb.toString(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/response/HttpResponse.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http.response; 2 | 3 | import java.io.InputStream; 4 | 5 | /** 6 | * Created by huxq17 on 2015/11/28. 7 | */ 8 | public class HttpResponse { 9 | private long contentLength; 10 | private ResponseType type; 11 | private int code; 12 | private Body mBody; 13 | 14 | public HttpResponse() { 15 | mBody = new Body(); 16 | } 17 | 18 | public void setCode(int code) { 19 | this.code = code; 20 | } 21 | 22 | public int code() { 23 | return code; 24 | } 25 | 26 | public class Body { 27 | private String string; 28 | private InputStream inputStream; 29 | 30 | public void setString(String string) { 31 | this.string = string; 32 | } 33 | 34 | public String string() { 35 | check(ResponseType.String); 36 | return string; 37 | } 38 | 39 | public void setInputStream(InputStream inputStream) { 40 | check(ResponseType.InputStream); 41 | this.inputStream = inputStream; 42 | } 43 | 44 | public InputStream getInputStream() { 45 | return inputStream; 46 | } 47 | } 48 | 49 | public Body body() { 50 | return mBody; 51 | } 52 | 53 | public void setContentLength(long contentLength) { 54 | this.contentLength = contentLength; 55 | } 56 | 57 | 58 | private void check(ResponseType requstType) { 59 | if (requstType != type) { 60 | StringBuffer stringBuffer = new StringBuffer(); 61 | stringBuffer.append("Response type mismatch,you need type is ").append(requstType) 62 | .append(" ,but your configuration is ").append(type).append(" ,so you should config responseType like this:"); 63 | switch (requstType) { 64 | case String: 65 | stringBuffer.append(" builder.setResponseType(ResponseType.String);"); 66 | break; 67 | case InputStream: 68 | stringBuffer.append(" builder.setResponseType(ResponseType.InputStream);"); 69 | break; 70 | } 71 | throw new RuntimeException(stringBuffer.toString()); 72 | } 73 | } 74 | 75 | public long getContentLength() { 76 | return contentLength; 77 | } 78 | 79 | public void setResponseType(ResponseType type) { 80 | this.type = type; 81 | } 82 | 83 | public static String getString(Object result) { 84 | if (result instanceof HttpResponse) { 85 | HttpResponse httpResponse = (HttpResponse) result; 86 | return httpResponse.body().string(); 87 | } 88 | return null; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/http/response/ResponseType.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.http.response; 2 | 3 | /** 4 | * 网络请求返回的类型 5 | * 6 | *

HttpRequest.Builder builder = new HttpRequest.Builder(); 7 | *

builder.url(url); 8 | *

addHeaders(builder, headers); 9 | *

//网络请求返回的默认类型就是string,如下载文件和加载图片需要用到InputStream,则设置为ResponseType.InputStream 10 | *

builder.setResponseType(ResponseType.InputStream); 11 | *

mHttpBase.get(builder.build(), listener, tag); 12 | */ 13 | public enum ResponseType { 14 | String("String"), InputStream("InputStream"); 15 | private final String type; 16 | 17 | ResponseType(String type) { 18 | this.type = type; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return type; 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/utils/DataCleanManager.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.utils; 2 | 3 | /* * 文 件 名: DataCleanManager.java * 描 述: 主要功能有清除内/外缓存,清除数据库,清除sharedPreference,清除files和清除自定义目录 */ 4 | 5 | import android.content.Context; 6 | import android.os.Environment; 7 | 8 | import java.io.File; 9 | 10 | /** 11 | * 本应用数据清除管理器 12 | */ 13 | public class DataCleanManager { 14 | /** 15 | * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * * @param context 16 | */ 17 | public static void cleanInternalCache(Context context) { 18 | deleteFilesByDirectory(context.getCacheDir()); 19 | } 20 | 21 | /** 22 | * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases) * * @param context 23 | */ 24 | public static void cleanDatabases(Context context) { 25 | deleteFilesByDirectory(new File("/data/data/" 26 | + context.getPackageName() + "/databases")); 27 | } 28 | 29 | /** 30 | * * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) * * @param 31 | * context 32 | */ 33 | public static void cleanSharedPreference(Context context) { 34 | deleteFilesByDirectory(new File("/data/data/" 35 | + context.getPackageName() + "/shared_prefs")); 36 | } 37 | 38 | /** 39 | * 按名字清除本应用数据库 * * @param context * @param dbName 40 | */ 41 | public static void cleanDatabaseByName(Context context, String dbName) { 42 | context.deleteDatabase(dbName); 43 | } 44 | 45 | /** 46 | * 清除/data/data/com.xxx.xxx/files下的内容 * * @param context 47 | */ 48 | public static void cleanFiles(Context context) { 49 | deleteFilesByDirectory(context.getFilesDir()); 50 | } 51 | 52 | /** 53 | * * 清除外部cache下的内容(/mnt/sdcard/android/data/com.xxx.xxx/cache) * * @param 54 | * context 55 | */ 56 | public static void cleanExternalCache(Context context) { 57 | if (Environment.getExternalStorageState().equals( 58 | Environment.MEDIA_MOUNTED)) { 59 | deleteFilesByDirectory(context.getExternalCacheDir()); 60 | } 61 | } 62 | 63 | /** 64 | * 清除自定义路径下的文件,使用需小心,请不要误删。而且只支持目录下的文件删除 * * @param filePath 65 | */ 66 | public static void cleanCustomCache(String filePath) { 67 | deleteFilesByDirectory(new File(filePath)); 68 | } 69 | 70 | /** 71 | * 清除本应用所有的数据 * * @param context * @param filepath 72 | */ 73 | public static void cleanApplicationData(Context context, String... filepath) { 74 | cleanInternalCache(context); 75 | cleanExternalCache(context); 76 | cleanDatabases(context); 77 | cleanSharedPreference(context); 78 | cleanFiles(context); 79 | for (String filePath : filepath) { 80 | cleanCustomCache(filePath); 81 | } 82 | } 83 | 84 | /** 85 | * 删除方法 这里只会删除某个文件夹下的文件,如果传入的directory是个文件,将不做处理 * * @param directory 86 | */ 87 | private static void deleteFilesByDirectory(File directory) { 88 | if (directory != null && directory.exists() && directory.isDirectory()) { 89 | for (File item : directory.listFiles()) { 90 | item.delete(); 91 | } 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /app/src/main/java/com/andbase/demo/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package com.andbase.demo.utils; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.text.TextUtils; 7 | 8 | import java.io.Closeable; 9 | import java.io.File; 10 | 11 | /** 12 | * Created by Administrator on 2015/11/30. 13 | */ 14 | public class Utils { 15 | public static void install(Context context, String path) { 16 | if (context == null) { 17 | throw new RuntimeException("context==null"); 18 | } 19 | Intent intent = new Intent(Intent.ACTION_VIEW); 20 | intent.setDataAndType(Uri.fromFile(new File(path)), 21 | "application/vnd.android.package-archive"); 22 | context.startActivity(intent); 23 | } 24 | 25 | public static boolean deleteFileSafely(File file) { 26 | if (file != null) { 27 | String tmpPath = file.getParent() + File.separator + System.currentTimeMillis(); 28 | File tmp = new File(tmpPath); 29 | file.renameTo(tmp); 30 | return tmp.delete(); 31 | } 32 | return false; 33 | } 34 | 35 | public static void createDirIfNotExists(String fileDir) { 36 | File dir = new File(fileDir); 37 | if (!dir.exists()) { 38 | dir.mkdirs(); 39 | } 40 | } 41 | 42 | /** 43 | * 删除文件 44 | */ 45 | public static boolean delete(String filePathName) { 46 | if (TextUtils.isEmpty(filePathName)) return false; 47 | File file = new File(filePathName); 48 | return deleteFileSafely(file); 49 | } 50 | 51 | /** 52 | * 关闭流 53 | * 54 | * @param closeable closeable 55 | */ 56 | public static void close(Closeable closeable) { 57 | try { 58 | if (closeable != null) closeable.close(); 59 | } catch (Throwable e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | 64 | /** 65 | * 重命名 66 | * 67 | * @param filePathName 原始文件路径 68 | * @param newPathName 新的文件路径 69 | * @return 是否成功 70 | */ 71 | public static boolean rename(String filePathName, String newPathName) { 72 | if (TextUtils.isEmpty(filePathName)) return false; 73 | if (TextUtils.isEmpty(newPathName)) return false; 74 | 75 | delete(newPathName); 76 | 77 | File file = new File(filePathName); 78 | File newFile = new File(newPathName); 79 | if (!file.exists()) { 80 | return false; 81 | } 82 | File parentFile = newFile.getParentFile(); 83 | if (!parentFile.exists()) { 84 | parentFile.mkdirs(); 85 | } 86 | return file.renameTo(newFile); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/act_event.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 |